[{"id":35865,"web_url":"https://patchwork.libcamera.org/comment/35865/","msgid":"<175818021910.17312.6511880578495176271@localhost>","date":"2025-09-18T07:23:39","subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Laurent,\n\nThank you for the patch.\n\nQuoting Laurent Pinchart (2025-09-17 22:17:38)\n> The libcamera documentation comprises two parts: pages generated by\n> Sphinx into the Documentation/html/ directory within the build tree, and\n> API reference documentation generated by Doxygen into\n> Documentation/internal-api-html/ and Documentation/api-html/. The two\n> parts are generated separately, but link to each other.\n> \n> From Sphinx to Doxygen, we use the doxylink extension for Sphinx to\n> generate links to the Doxygen pages corresponding to API elements. The\n> extension needs to be configured with the paths to the Doxygen\n> documentation, which are set based on the html/, api-html/ and\n> internal-api-html/ directories being placed side by side in the same\n> parent directory.\n> \n> Furthermore, we also want to link to the API documentation from the\n> Sphinx toctree. As toctrees can only link to pages within the Sphinx\n> documents tree (or to http URLs), we have placeholder .rst documents for\n> api-html and internal-api-html in the Sphinx documentation tree. Those\n> generate the Documentation/html/internal-api-html/index.html and\n> Documentation/html/api-html/index.html placeholder files in the build\n> tree.\n\nWe could mention the ../api-html path in these placeholders so that\nsomeone reading the docs from the build dir gets a hint where to look.\n\n> \n> The other way around, the API documentation's introduction pagelinks to\n> Sphinx pages using relative paths. Those paths are hardcoded based on\n> the api-html/ and internal-api-html/ directories being children of the\n> html/ directory.\n> \n> This results in links being broken in different ways in the build tree,\n> as well as in the installation directory: the toctree links direct to\n> the placeholder pages within the html/ directory instead of the Doxygen\n> documentation in sibling directories, and the Doxygen introduction links\n> to Sphinx are simply broken. When publishing documentation on the\n> website we work around those issues by patching several files and moving\n\nDo we really patch files? To my understanding we only do the move that\nis also done by the install step now. Or am I missing something? We\ncould actually do a meson install --destdir= there.\n\n> the api-html/ and internal-api-html/ directories to the html/ directory.\n> \n> Fixing this is surprisingly difficult. The toctree links can't be\n> changed to point to a path outside of the Sphinx document tree as this\n> isn't supported by Sphinx. Using http URLs would link to the\n> libcamera.org website inside of local documentation, which isn't\n> acceptable. It may be possible to develop a Sphinx extension to patch\n> the toctree after it gets parsed, but that would be complex and likely\n> fragile. Modifying the install path of the Doxygen documentation to\n> html/api-html/ and html/internal-api-html/ causes issues as the Sphinx\n> documentation will then overwrite the Doxygen index.html files with the\n> placeholder indexes. Creating symlinks from html/api-html/ to api-html/\n> in the installation directory causes similar problems if 'meson install'\n> is run twice. Creating the symlinks in the build directory (which was\n> attempted with a custom Sphinx extension) is also a no-go: starting with\n> meson v1.8.0, installing symlinks to directories causes an exception due\n> to a bug in meson.\n> \n> The right solution is probably to investigate usage of the doxysphinx\n> extension. As that's no small amount of work, let's start with a\n> non-perfect but simple improvement: configure doxylink based on the\n> api-html/ and internal-api-html/ directories being children of the\n> Sphinx html/ documentation, and move those two API documentation\n> directories to html/ during installation with a post-install script.\n> This fixes links in the installation directory. Links in the build\n> directory remain broken, but that is not a regression.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nPhew, that was a ride. Now the initial cp moved into the install step. I\nlike that workaround.\n\nReviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\n> ---\n>  Documentation/conf.py.in         |  4 ++--\n>  Documentation/install-doxygen.sh | 18 ++++++++++++++++++\n>  Documentation/meson.build        |  3 +++\n>  3 files changed, 23 insertions(+), 2 deletions(-)\n>  create mode 100755 Documentation/install-doxygen.sh\n> \n> diff --git a/Documentation/conf.py.in b/Documentation/conf.py.in\n> index 34fa3956f49e..2c75a75799e6 100644\n> --- a/Documentation/conf.py.in\n> +++ b/Documentation/conf.py.in\n> @@ -75,11 +75,11 @@ pygments_style = None\n>  doxylink = {\n>      'doxy-pub': (\n>          '@TOP_BUILDDIR@/Documentation/api-html/tagfile.xml',\n> -        '../api-html/',\n> +        'api-html/',\n>      ),\n>      'doxy-int': (\n>          '@TOP_BUILDDIR@/Documentation/internal-api-html/tagfile.xml',\n> -        '../internal-api-html/',\n> +        'internal-api-html/',\n>      ),\n>  }\n>  \n> diff --git a/Documentation/install-doxygen.sh b/Documentation/install-doxygen.sh\n> new file mode 100755\n> index 000000000000..ea5a19dc8fda\n> --- /dev/null\n> +++ b/Documentation/install-doxygen.sh\n> @@ -0,0 +1,18 @@\n> +#!/bin/sh\n> +# SPDX-License-Identifier: GPL-2.0-or-later\n> +# Copyright (C) 2025, Ideas on Board Oy\n> +#\n> +# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> +#\n> +# Move Doxygen-generated API documentation to correct location\n> +\n> +doc_dir=\"${MESON_INSTALL_DESTDIR_PREFIX}/$1\"\n> +shift\n> +dirs=\"$*\"\n> +\n> +echo \"Moving API documentation\"\n> +\n> +for dir in $dirs ; do\n> +       rm -r \"${doc_dir}/html/${dir}\"\n> +       mv \"${doc_dir}/${dir}\" \"${doc_dir}/html/\"\n> +done\n> diff --git a/Documentation/meson.build b/Documentation/meson.build\n> index 8cf7775902f3..022770968fcf 100644\n> --- a/Documentation/meson.build\n> +++ b/Documentation/meson.build\n> @@ -193,6 +193,9 @@ if sphinx.found()\n>                    install_dir : doc_install_dir,\n>                    install_tag : 'doc')\n>  \n> +    meson.add_install_script('install-doxygen.sh', doc_install_dir,\n> +                             'api-html', 'internal-api-html')\n> +\n>      custom_target('documentation-linkcheck',\n>                    command : [sphinx, '-W', '-b', 'linkcheck',\n>                               '-c', sphinx_conf_dir,\n> -- \n> Regards,\n> \n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 373C8C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 07:23:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C5F6F6936D;\n\tThu, 18 Sep 2025 09:23:45 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3097D62C39\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 09:23:42 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:ace3:d2c2:5eff:9cc5])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 542E06DF;\n\tThu, 18 Sep 2025 09:22:22 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"AWX7EuGm\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758180142;\n\tbh=BDKmaKggrbNa5LJfgsjvhIkiYbxGDA+6bJ9AfqSsNBY=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=AWX7EuGmhlYo5qV6vZS8NIqiwf6OdgQMlhQSucXfHiXLpUBc6G9IOLGNeOWDZ4Red\n\te1skWIO0Y0pqaBG3zAWQDE5TICTwyh8jXm+8RYDVTBRQSfnxlstu9VKmNGIYCbLQrV\n\t/fRvcJ0UrN3KTZv4pfLjWFMVBA8AdOPPgPGEDlN0=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>","References":"<20250917201742.16406-1-laurent.pinchart@ideasonboard.com>\n\t<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>","Subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 18 Sep 2025 09:23:39 +0200","Message-ID":"<175818021910.17312.6511880578495176271@localhost>","User-Agent":"alot/0.12.dev8+g2c003385c862.d20250602","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35869,"web_url":"https://patchwork.libcamera.org/comment/35869/","msgid":"<5fb842e8-de80-469a-8920-b89e3e1c2f46@ideasonboard.com>","date":"2025-09-18T07:48:05","subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2025. 09. 17. 22:17 keltezéssel, Laurent Pinchart írta:\n> The libcamera documentation comprises two parts: pages generated by\n> Sphinx into the Documentation/html/ directory within the build tree, and\n> API reference documentation generated by Doxygen into\n> Documentation/internal-api-html/ and Documentation/api-html/. The two\n> parts are generated separately, but link to each other.\n> \n>  From Sphinx to Doxygen, we use the doxylink extension for Sphinx to\n> generate links to the Doxygen pages corresponding to API elements. The\n> extension needs to be configured with the paths to the Doxygen\n> documentation, which are set based on the html/, api-html/ and\n> internal-api-html/ directories being placed side by side in the same\n> parent directory.\n> \n> Furthermore, we also want to link to the API documentation from the\n> Sphinx toctree. As toctrees can only link to pages within the Sphinx\n> documents tree (or to http URLs), we have placeholder .rst documents for\n> api-html and internal-api-html in the Sphinx documentation tree. Those\n> generate the Documentation/html/internal-api-html/index.html and\n> Documentation/html/api-html/index.html placeholder files in the build\n> tree.\n> \n> The other way around, the API documentation's introduction pagelinks to\n> Sphinx pages using relative paths. Those paths are hardcoded based on\n> the api-html/ and internal-api-html/ directories being children of the\n> html/ directory.\n> \n> This results in links being broken in different ways in the build tree,\n> as well as in the installation directory: the toctree links direct to\n> the placeholder pages within the html/ directory instead of the Doxygen\n> documentation in sibling directories, and the Doxygen introduction links\n> to Sphinx are simply broken. When publishing documentation on the\n> website we work around those issues by patching several files and moving\n> the api-html/ and internal-api-html/ directories to the html/ directory.\n> \n> Fixing this is surprisingly difficult. The toctree links can't be\n> changed to point to a path outside of the Sphinx document tree as this\n> isn't supported by Sphinx. Using http URLs would link to the\n> libcamera.org website inside of local documentation, which isn't\n> acceptable. It may be possible to develop a Sphinx extension to patch\n> the toctree after it gets parsed, but that would be complex and likely\n> fragile. Modifying the install path of the Doxygen documentation to\n> html/api-html/ and html/internal-api-html/ causes issues as the Sphinx\n> documentation will then overwrite the Doxygen index.html files with the\n> placeholder indexes. Creating symlinks from html/api-html/ to api-html/\n> in the installation directory causes similar problems if 'meson install'\n> is run twice. Creating the symlinks in the build directory (which was\n> attempted with a custom Sphinx extension) is also a no-go: starting with\n> meson v1.8.0, installing symlinks to directories causes an exception due\n> to a bug in meson.\n> \n> The right solution is probably to investigate usage of the doxysphinx\n> extension. As that's no small amount of work, let's start with a\n> non-perfect but simple improvement: configure doxylink based on the\n> api-html/ and internal-api-html/ directories being children of the\n> Sphinx html/ documentation, and move those two API documentation\n> directories to html/ during installation with a post-install script.\n> This fixes links in the installation directory. Links in the build\n> directory remain broken, but that is not a regression.\n\nsphinx -> doxygen links were working in the build directory as far as I can tell.\nBut not anymore after changing the doxylinks configuration here. Which links does\nthe above refer to?\n\n\nRegards,\nBarnabás Pőcze\n\n\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>   Documentation/conf.py.in         |  4 ++--\n>   Documentation/install-doxygen.sh | 18 ++++++++++++++++++\n>   Documentation/meson.build        |  3 +++\n>   3 files changed, 23 insertions(+), 2 deletions(-)\n>   create mode 100755 Documentation/install-doxygen.sh\n> \n> diff --git a/Documentation/conf.py.in b/Documentation/conf.py.in\n> index 34fa3956f49e..2c75a75799e6 100644\n> --- a/Documentation/conf.py.in\n> +++ b/Documentation/conf.py.in\n> @@ -75,11 +75,11 @@ pygments_style = None\n>   doxylink = {\n>       'doxy-pub': (\n>           '@TOP_BUILDDIR@/Documentation/api-html/tagfile.xml',\n> -        '../api-html/',\n> +        'api-html/',\n>       ),\n>       'doxy-int': (\n>           '@TOP_BUILDDIR@/Documentation/internal-api-html/tagfile.xml',\n> -        '../internal-api-html/',\n> +        'internal-api-html/',\n>       ),\n>   }\n>   \n> diff --git a/Documentation/install-doxygen.sh b/Documentation/install-doxygen.sh\n> new file mode 100755\n> index 000000000000..ea5a19dc8fda\n> --- /dev/null\n> +++ b/Documentation/install-doxygen.sh\n> @@ -0,0 +1,18 @@\n> +#!/bin/sh\n> +# SPDX-License-Identifier: GPL-2.0-or-later\n> +# Copyright (C) 2025, Ideas on Board Oy\n> +#\n> +# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> +#\n> +# Move Doxygen-generated API documentation to correct location\n> +\n> +doc_dir=\"${MESON_INSTALL_DESTDIR_PREFIX}/$1\"\n> +shift\n> +dirs=\"$*\"\n> +\n> +echo \"Moving API documentation\"\n> +\n> +for dir in $dirs ; do\n> +\trm -r \"${doc_dir}/html/${dir}\"\n> +\tmv \"${doc_dir}/${dir}\" \"${doc_dir}/html/\"\n> +done\n> diff --git a/Documentation/meson.build b/Documentation/meson.build\n> index 8cf7775902f3..022770968fcf 100644\n> --- a/Documentation/meson.build\n> +++ b/Documentation/meson.build\n> @@ -193,6 +193,9 @@ if sphinx.found()\n>                     install_dir : doc_install_dir,\n>                     install_tag : 'doc')\n>   \n> +    meson.add_install_script('install-doxygen.sh', doc_install_dir,\n> +                             'api-html', 'internal-api-html')\n> +\n>       custom_target('documentation-linkcheck',\n>                     command : [sphinx, '-W', '-b', 'linkcheck',\n>                                '-c', sphinx_conf_dir,","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id CEBC7BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 07:48:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8F9666936F;\n\tThu, 18 Sep 2025 09:48:10 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 88C6162C39\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 09:48:08 +0200 (CEST)","from [192.168.33.22] (185.221.142.115.nat.pool.zt.hu\n\t[185.221.142.115])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EE57CC72;\n\tThu, 18 Sep 2025 09:46:48 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Q1phzoqj\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758181609;\n\tbh=WvE9VUGcTcomNgFVvpwRbiO1f62UxwmsfjCH6yYa3SE=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=Q1phzoqjkK+zuNixHKLGFchGobMVpPn6p9AgYOhWQJ4DXWOWwdLMr9GHUKqKkXp6B\n\t1kqiVBGvaoKms9IHZytFXQq6Ps3nglgHbru73Q08BWMnVEfge5z9t77gHPCfcmz9TK\n\tDJSsvekKoDEeJRH+wRWR26DiUc48KZ2LaVZGb7y0=","Message-ID":"<5fb842e8-de80-469a-8920-b89e3e1c2f46@ideasonboard.com>","Date":"Thu, 18 Sep 2025 09:48:05 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250917201742.16406-1-laurent.pinchart@ideasonboard.com>\n\t<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35870,"web_url":"https://patchwork.libcamera.org/comment/35870/","msgid":"<20250918082806.GE10145@pendragon.ideasonboard.com>","date":"2025-09-18T08:28:06","subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Sep 18, 2025 at 09:48:05AM +0200, Barnabás Pőcze wrote:\n> 2025. 09. 17. 22:17 keltezéssel, Laurent Pinchart írta:\n> > The libcamera documentation comprises two parts: pages generated by\n> > Sphinx into the Documentation/html/ directory within the build tree, and\n> > API reference documentation generated by Doxygen into\n> > Documentation/internal-api-html/ and Documentation/api-html/. The two\n> > parts are generated separately, but link to each other.\n> > \n> >  From Sphinx to Doxygen, we use the doxylink extension for Sphinx to\n> > generate links to the Doxygen pages corresponding to API elements. The\n> > extension needs to be configured with the paths to the Doxygen\n> > documentation, which are set based on the html/, api-html/ and\n> > internal-api-html/ directories being placed side by side in the same\n> > parent directory.\n> > \n> > Furthermore, we also want to link to the API documentation from the\n> > Sphinx toctree. As toctrees can only link to pages within the Sphinx\n> > documents tree (or to http URLs), we have placeholder .rst documents for\n> > api-html and internal-api-html in the Sphinx documentation tree. Those\n> > generate the Documentation/html/internal-api-html/index.html and\n> > Documentation/html/api-html/index.html placeholder files in the build\n> > tree.\n> > \n> > The other way around, the API documentation's introduction pagelinks to\n> > Sphinx pages using relative paths. Those paths are hardcoded based on\n> > the api-html/ and internal-api-html/ directories being children of the\n> > html/ directory.\n> > \n> > This results in links being broken in different ways in the build tree,\n> > as well as in the installation directory: the toctree links direct to\n> > the placeholder pages within the html/ directory instead of the Doxygen\n> > documentation in sibling directories, and the Doxygen introduction links\n> > to Sphinx are simply broken. When publishing documentation on the\n> > website we work around those issues by patching several files and moving\n> > the api-html/ and internal-api-html/ directories to the html/ directory.\n> > \n> > Fixing this is surprisingly difficult. The toctree links can't be\n> > changed to point to a path outside of the Sphinx document tree as this\n> > isn't supported by Sphinx. Using http URLs would link to the\n> > libcamera.org website inside of local documentation, which isn't\n> > acceptable. It may be possible to develop a Sphinx extension to patch\n> > the toctree after it gets parsed, but that would be complex and likely\n> > fragile. Modifying the install path of the Doxygen documentation to\n> > html/api-html/ and html/internal-api-html/ causes issues as the Sphinx\n> > documentation will then overwrite the Doxygen index.html files with the\n> > placeholder indexes. Creating symlinks from html/api-html/ to api-html/\n> > in the installation directory causes similar problems if 'meson install'\n> > is run twice. Creating the symlinks in the build directory (which was\n> > attempted with a custom Sphinx extension) is also a no-go: starting with\n> > meson v1.8.0, installing symlinks to directories causes an exception due\n> > to a bug in meson.\n> > \n> > The right solution is probably to investigate usage of the doxysphinx\n> > extension. As that's no small amount of work, let's start with a\n> > non-perfect but simple improvement: configure doxylink based on the\n> > api-html/ and internal-api-html/ directories being children of the\n> > Sphinx html/ documentation, and move those two API documentation\n> > directories to html/ during installation with a post-install script.\n> > This fixes links in the installation directory. Links in the build\n> > directory remain broken, but that is not a regression.\n> \n> sphinx -> doxygen links were working in the build directory as far as I can tell.\n> But not anymore after changing the doxylinks configuration here. Which links does\n> the above refer to?\n\nThe toctree links are currently broken, and so are the links from\ndoxygen to sphinx. We will have a larger number of broken sphinx ->\ndoxyen links in the build tree with this patch, but we'll fix the\ninstallation directory. As the build tree has broken links today\nalready, I think that's an acceptable compromise. I also think the\ninstallation directory is more important, as in the build tree people\nalso have access to sources. Application developers in particular are\nless likely to read documentation from the libcamera build tree, they\nmay not even have the libcamera source tree.\n\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >   Documentation/conf.py.in         |  4 ++--\n> >   Documentation/install-doxygen.sh | 18 ++++++++++++++++++\n> >   Documentation/meson.build        |  3 +++\n> >   3 files changed, 23 insertions(+), 2 deletions(-)\n> >   create mode 100755 Documentation/install-doxygen.sh\n> > \n> > diff --git a/Documentation/conf.py.in b/Documentation/conf.py.in\n> > index 34fa3956f49e..2c75a75799e6 100644\n> > --- a/Documentation/conf.py.in\n> > +++ b/Documentation/conf.py.in\n> > @@ -75,11 +75,11 @@ pygments_style = None\n> >   doxylink = {\n> >       'doxy-pub': (\n> >           '@TOP_BUILDDIR@/Documentation/api-html/tagfile.xml',\n> > -        '../api-html/',\n> > +        'api-html/',\n> >       ),\n> >       'doxy-int': (\n> >           '@TOP_BUILDDIR@/Documentation/internal-api-html/tagfile.xml',\n> > -        '../internal-api-html/',\n> > +        'internal-api-html/',\n> >       ),\n> >   }\n> >   \n> > diff --git a/Documentation/install-doxygen.sh b/Documentation/install-doxygen.sh\n> > new file mode 100755\n> > index 000000000000..ea5a19dc8fda\n> > --- /dev/null\n> > +++ b/Documentation/install-doxygen.sh\n> > @@ -0,0 +1,18 @@\n> > +#!/bin/sh\n> > +# SPDX-License-Identifier: GPL-2.0-or-later\n> > +# Copyright (C) 2025, Ideas on Board Oy\n> > +#\n> > +# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > +#\n> > +# Move Doxygen-generated API documentation to correct location\n> > +\n> > +doc_dir=\"${MESON_INSTALL_DESTDIR_PREFIX}/$1\"\n> > +shift\n> > +dirs=\"$*\"\n> > +\n> > +echo \"Moving API documentation\"\n> > +\n> > +for dir in $dirs ; do\n> > +\trm -r \"${doc_dir}/html/${dir}\"\n> > +\tmv \"${doc_dir}/${dir}\" \"${doc_dir}/html/\"\n> > +done\n> > diff --git a/Documentation/meson.build b/Documentation/meson.build\n> > index 8cf7775902f3..022770968fcf 100644\n> > --- a/Documentation/meson.build\n> > +++ b/Documentation/meson.build\n> > @@ -193,6 +193,9 @@ if sphinx.found()\n> >                     install_dir : doc_install_dir,\n> >                     install_tag : 'doc')\n> >   \n> > +    meson.add_install_script('install-doxygen.sh', doc_install_dir,\n> > +                             'api-html', 'internal-api-html')\n> > +\n> >       custom_target('documentation-linkcheck',\n> >                     command : [sphinx, '-W', '-b', 'linkcheck',\n> >                                '-c', sphinx_conf_dir,","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id CCBAFC328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 08:28:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DD35D62C39;\n\tThu, 18 Sep 2025 10:28:36 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5071762C39\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 10:28:35 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 900AEC72;\n\tThu, 18 Sep 2025 10:27:15 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"qmkhy/Xf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758184035;\n\tbh=KTxqnd1mfUx/J3qMSFfdEZgjixOGiPsnLDUUYf2vQy4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=qmkhy/XfOJCUwvI8FK790AiARVseeEcqzrJyMqlNAuPxtSCLgLj29zAJVhRoj78Gi\n\tC52Uu0BER3i49BFvu9+gKV7eEhARWft67xp9ha4FRFehu6Ikl1Nr5Zjh0jeNV4T9s1\n\tKiidCyhY5Ly3YhanoPPV6L8oFNrv3hjVk55HHvPs=","Date":"Thu, 18 Sep 2025 11:28:06 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","Message-ID":"<20250918082806.GE10145@pendragon.ideasonboard.com>","References":"<20250917201742.16406-1-laurent.pinchart@ideasonboard.com>\n\t<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>\n\t<5fb842e8-de80-469a-8920-b89e3e1c2f46@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<5fb842e8-de80-469a-8920-b89e3e1c2f46@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35871,"web_url":"https://patchwork.libcamera.org/comment/35871/","msgid":"<20250918082956.GF10145@pendragon.ideasonboard.com>","date":"2025-09-18T08:29:56","subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Sep 18, 2025 at 09:23:39AM +0200, Stefan Klug wrote:\n> Hi Laurent,\n> \n> Thank you for the patch.\n> \n> Quoting Laurent Pinchart (2025-09-17 22:17:38)\n> > The libcamera documentation comprises two parts: pages generated by\n> > Sphinx into the Documentation/html/ directory within the build tree, and\n> > API reference documentation generated by Doxygen into\n> > Documentation/internal-api-html/ and Documentation/api-html/. The two\n> > parts are generated separately, but link to each other.\n> > \n> > From Sphinx to Doxygen, we use the doxylink extension for Sphinx to\n> > generate links to the Doxygen pages corresponding to API elements. The\n> > extension needs to be configured with the paths to the Doxygen\n> > documentation, which are set based on the html/, api-html/ and\n> > internal-api-html/ directories being placed side by side in the same\n> > parent directory.\n> > \n> > Furthermore, we also want to link to the API documentation from the\n> > Sphinx toctree. As toctrees can only link to pages within the Sphinx\n> > documents tree (or to http URLs), we have placeholder .rst documents for\n> > api-html and internal-api-html in the Sphinx documentation tree. Those\n> > generate the Documentation/html/internal-api-html/index.html and\n> > Documentation/html/api-html/index.html placeholder files in the build\n> > tree.\n> \n> We could mention the ../api-html path in these placeholders so that\n> someone reading the docs from the build dir gets a hint where to look.\n> \n> > The other way around, the API documentation's introduction pagelinks to\n> > Sphinx pages using relative paths. Those paths are hardcoded based on\n> > the api-html/ and internal-api-html/ directories being children of the\n> > html/ directory.\n> > \n> > This results in links being broken in different ways in the build tree,\n> > as well as in the installation directory: the toctree links direct to\n> > the placeholder pages within the html/ directory instead of the Doxygen\n> > documentation in sibling directories, and the Doxygen introduction links\n> > to Sphinx are simply broken. When publishing documentation on the\n> > website we work around those issues by patching several files and moving\n> \n> Do we really patch files? To my understanding we only do the move that\n> is also done by the install step now. Or am I missing something?\n\nWe don't patch, indeed. We override the sphinx options with a custom\nconf.py. I'll change that in the commit message and write\n\nWhen publishing documentation on the website we work around those issues\nby overriding conf.py with a custom version and moving the api-html/ and\ninternal-api-html/ directories to the html/ directory.\n\n> We could actually do a meson install --destdir= there.\n> \n> > the api-html/ and internal-api-html/ directories to the html/ directory.\n> > \n> > Fixing this is surprisingly difficult. The toctree links can't be\n> > changed to point to a path outside of the Sphinx document tree as this\n> > isn't supported by Sphinx. Using http URLs would link to the\n> > libcamera.org website inside of local documentation, which isn't\n> > acceptable. It may be possible to develop a Sphinx extension to patch\n> > the toctree after it gets parsed, but that would be complex and likely\n> > fragile. Modifying the install path of the Doxygen documentation to\n> > html/api-html/ and html/internal-api-html/ causes issues as the Sphinx\n> > documentation will then overwrite the Doxygen index.html files with the\n> > placeholder indexes. Creating symlinks from html/api-html/ to api-html/\n> > in the installation directory causes similar problems if 'meson install'\n> > is run twice. Creating the symlinks in the build directory (which was\n> > attempted with a custom Sphinx extension) is also a no-go: starting with\n> > meson v1.8.0, installing symlinks to directories causes an exception due\n> > to a bug in meson.\n> > \n> > The right solution is probably to investigate usage of the doxysphinx\n> > extension. As that's no small amount of work, let's start with a\n> > non-perfect but simple improvement: configure doxylink based on the\n> > api-html/ and internal-api-html/ directories being children of the\n> > Sphinx html/ documentation, and move those two API documentation\n> > directories to html/ during installation with a post-install script.\n> > This fixes links in the installation directory. Links in the build\n> > directory remain broken, but that is not a regression.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> Phew, that was a ride. Now the initial cp moved into the install step. I\n> like that workaround.\n> \n> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> \n> > ---\n> >  Documentation/conf.py.in         |  4 ++--\n> >  Documentation/install-doxygen.sh | 18 ++++++++++++++++++\n> >  Documentation/meson.build        |  3 +++\n> >  3 files changed, 23 insertions(+), 2 deletions(-)\n> >  create mode 100755 Documentation/install-doxygen.sh\n> > \n> > diff --git a/Documentation/conf.py.in b/Documentation/conf.py.in\n> > index 34fa3956f49e..2c75a75799e6 100644\n> > --- a/Documentation/conf.py.in\n> > +++ b/Documentation/conf.py.in\n> > @@ -75,11 +75,11 @@ pygments_style = None\n> >  doxylink = {\n> >      'doxy-pub': (\n> >          '@TOP_BUILDDIR@/Documentation/api-html/tagfile.xml',\n> > -        '../api-html/',\n> > +        'api-html/',\n> >      ),\n> >      'doxy-int': (\n> >          '@TOP_BUILDDIR@/Documentation/internal-api-html/tagfile.xml',\n> > -        '../internal-api-html/',\n> > +        'internal-api-html/',\n> >      ),\n> >  }\n> >  \n> > diff --git a/Documentation/install-doxygen.sh b/Documentation/install-doxygen.sh\n> > new file mode 100755\n> > index 000000000000..ea5a19dc8fda\n> > --- /dev/null\n> > +++ b/Documentation/install-doxygen.sh\n> > @@ -0,0 +1,18 @@\n> > +#!/bin/sh\n> > +# SPDX-License-Identifier: GPL-2.0-or-later\n> > +# Copyright (C) 2025, Ideas on Board Oy\n> > +#\n> > +# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > +#\n> > +# Move Doxygen-generated API documentation to correct location\n> > +\n> > +doc_dir=\"${MESON_INSTALL_DESTDIR_PREFIX}/$1\"\n> > +shift\n> > +dirs=\"$*\"\n> > +\n> > +echo \"Moving API documentation\"\n> > +\n> > +for dir in $dirs ; do\n> > +       rm -r \"${doc_dir}/html/${dir}\"\n> > +       mv \"${doc_dir}/${dir}\" \"${doc_dir}/html/\"\n> > +done\n> > diff --git a/Documentation/meson.build b/Documentation/meson.build\n> > index 8cf7775902f3..022770968fcf 100644\n> > --- a/Documentation/meson.build\n> > +++ b/Documentation/meson.build\n> > @@ -193,6 +193,9 @@ if sphinx.found()\n> >                    install_dir : doc_install_dir,\n> >                    install_tag : 'doc')\n> >  \n> > +    meson.add_install_script('install-doxygen.sh', doc_install_dir,\n> > +                             'api-html', 'internal-api-html')\n> > +\n> >      custom_target('documentation-linkcheck',\n> >                    command : [sphinx, '-W', '-b', 'linkcheck',\n> >                               '-c', sphinx_conf_dir,","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id F3C10C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 08:30:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 15E3469370;\n\tThu, 18 Sep 2025 10:30:28 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8DCF762C39\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 10:30:26 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 9F2AB11A0; \n\tThu, 18 Sep 2025 10:29:06 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"CWeQP8Uv\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758184147;\n\tbh=jjqn3hacywfTR2ZQUKS0x0x1FqQEldHVaObv1MflPNU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=CWeQP8UvxIayDlGEffVjXN+/iZkdt9svNIS4brbV/uc/IHJ8TYSMk+Cx8v30Lgdgh\n\tHauY+6VTQmJgTJMisyWVIzGKSnuNK0ww3G/xYIcZ39JWrZEBgRG7eIiPr+Sj2idIlq\n\tAbk8Wbxp/rYAD0meEpofrKZSJK+3qMaRZxIDVUPo=","Date":"Thu, 18 Sep 2025 11:29:56 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","Message-ID":"<20250918082956.GF10145@pendragon.ideasonboard.com>","References":"<20250917201742.16406-1-laurent.pinchart@ideasonboard.com>\n\t<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>\n\t<175818021910.17312.6511880578495176271@localhost>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<175818021910.17312.6511880578495176271@localhost>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35884,"web_url":"https://patchwork.libcamera.org/comment/35884/","msgid":"<175819437731.17312.15780346867150389081@localhost>","date":"2025-09-18T11:19:37","subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2025-09-18 10:29:56)\n> On Thu, Sep 18, 2025 at 09:23:39AM +0200, Stefan Klug wrote:\n> > Hi Laurent,\n> > \n> > Thank you for the patch.\n> > \n> > Quoting Laurent Pinchart (2025-09-17 22:17:38)\n> > > The libcamera documentation comprises two parts: pages generated by\n> > > Sphinx into the Documentation/html/ directory within the build tree, and\n> > > API reference documentation generated by Doxygen into\n> > > Documentation/internal-api-html/ and Documentation/api-html/. The two\n> > > parts are generated separately, but link to each other.\n> > > \n> > > From Sphinx to Doxygen, we use the doxylink extension for Sphinx to\n> > > generate links to the Doxygen pages corresponding to API elements. The\n> > > extension needs to be configured with the paths to the Doxygen\n> > > documentation, which are set based on the html/, api-html/ and\n> > > internal-api-html/ directories being placed side by side in the same\n> > > parent directory.\n> > > \n> > > Furthermore, we also want to link to the API documentation from the\n> > > Sphinx toctree. As toctrees can only link to pages within the Sphinx\n> > > documents tree (or to http URLs), we have placeholder .rst documents for\n> > > api-html and internal-api-html in the Sphinx documentation tree. Those\n> > > generate the Documentation/html/internal-api-html/index.html and\n> > > Documentation/html/api-html/index.html placeholder files in the build\n> > > tree.\n> > \n> > We could mention the ../api-html path in these placeholders so that\n> > someone reading the docs from the build dir gets a hint where to look.\n> > \n> > > The other way around, the API documentation's introduction pagelinks to\n> > > Sphinx pages using relative paths. Those paths are hardcoded based on\n> > > the api-html/ and internal-api-html/ directories being children of the\n> > > html/ directory.\n> > > \n> > > This results in links being broken in different ways in the build tree,\n> > > as well as in the installation directory: the toctree links direct to\n> > > the placeholder pages within the html/ directory instead of the Doxygen\n> > > documentation in sibling directories, and the Doxygen introduction links\n> > > to Sphinx are simply broken. When publishing documentation on the\n> > > website we work around those issues by patching several files and moving\n> > \n> > Do we really patch files? To my understanding we only do the move that\n> > is also done by the install step now. Or am I missing something?\n> \n> We don't patch, indeed. We override the sphinx options with a custom\n> conf.py. I'll change that in the commit message and write\n> \n> When publishing documentation on the website we work around those issues\n> by overriding conf.py with a custom version and moving the api-html/ and\n> internal-api-html/ directories to the html/ directory.\n\nWhere does this override happen? I thought we only have a conf.py for\nthe website itself, but docs is now fully self contained (except\nreplicating the install step manually)?\n\nBest regards,\nStefan\n\n> \n> > We could actually do a meson install --destdir= there.\n> > \n> > > the api-html/ and internal-api-html/ directories to the html/ directory.\n> > > \n> > > Fixing this is surprisingly difficult. The toctree links can't be\n> > > changed to point to a path outside of the Sphinx document tree as this\n> > > isn't supported by Sphinx. Using http URLs would link to the\n> > > libcamera.org website inside of local documentation, which isn't\n> > > acceptable. It may be possible to develop a Sphinx extension to patch\n> > > the toctree after it gets parsed, but that would be complex and likely\n> > > fragile. Modifying the install path of the Doxygen documentation to\n> > > html/api-html/ and html/internal-api-html/ causes issues as the Sphinx\n> > > documentation will then overwrite the Doxygen index.html files with the\n> > > placeholder indexes. Creating symlinks from html/api-html/ to api-html/\n> > > in the installation directory causes similar problems if 'meson install'\n> > > is run twice. Creating the symlinks in the build directory (which was\n> > > attempted with a custom Sphinx extension) is also a no-go: starting with\n> > > meson v1.8.0, installing symlinks to directories causes an exception due\n> > > to a bug in meson.\n> > > \n> > > The right solution is probably to investigate usage of the doxysphinx\n> > > extension. As that's no small amount of work, let's start with a\n> > > non-perfect but simple improvement: configure doxylink based on the\n> > > api-html/ and internal-api-html/ directories being children of the\n> > > Sphinx html/ documentation, and move those two API documentation\n> > > directories to html/ during installation with a post-install script.\n> > > This fixes links in the installation directory. Links in the build\n> > > directory remain broken, but that is not a regression.\n> > > \n> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > \n> > Phew, that was a ride. Now the initial cp moved into the install step. I\n> > like that workaround.\n> > \n> > Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > \n> > > ---\n> > >  Documentation/conf.py.in         |  4 ++--\n> > >  Documentation/install-doxygen.sh | 18 ++++++++++++++++++\n> > >  Documentation/meson.build        |  3 +++\n> > >  3 files changed, 23 insertions(+), 2 deletions(-)\n> > >  create mode 100755 Documentation/install-doxygen.sh\n> > > \n> > > diff --git a/Documentation/conf.py.in b/Documentation/conf.py.in\n> > > index 34fa3956f49e..2c75a75799e6 100644\n> > > --- a/Documentation/conf.py.in\n> > > +++ b/Documentation/conf.py.in\n> > > @@ -75,11 +75,11 @@ pygments_style = None\n> > >  doxylink = {\n> > >      'doxy-pub': (\n> > >          '@TOP_BUILDDIR@/Documentation/api-html/tagfile.xml',\n> > > -        '../api-html/',\n> > > +        'api-html/',\n> > >      ),\n> > >      'doxy-int': (\n> > >          '@TOP_BUILDDIR@/Documentation/internal-api-html/tagfile.xml',\n> > > -        '../internal-api-html/',\n> > > +        'internal-api-html/',\n> > >      ),\n> > >  }\n> > >  \n> > > diff --git a/Documentation/install-doxygen.sh b/Documentation/install-doxygen.sh\n> > > new file mode 100755\n> > > index 000000000000..ea5a19dc8fda\n> > > --- /dev/null\n> > > +++ b/Documentation/install-doxygen.sh\n> > > @@ -0,0 +1,18 @@\n> > > +#!/bin/sh\n> > > +# SPDX-License-Identifier: GPL-2.0-or-later\n> > > +# Copyright (C) 2025, Ideas on Board Oy\n> > > +#\n> > > +# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > +#\n> > > +# Move Doxygen-generated API documentation to correct location\n> > > +\n> > > +doc_dir=\"${MESON_INSTALL_DESTDIR_PREFIX}/$1\"\n> > > +shift\n> > > +dirs=\"$*\"\n> > > +\n> > > +echo \"Moving API documentation\"\n> > > +\n> > > +for dir in $dirs ; do\n> > > +       rm -r \"${doc_dir}/html/${dir}\"\n> > > +       mv \"${doc_dir}/${dir}\" \"${doc_dir}/html/\"\n> > > +done\n> > > diff --git a/Documentation/meson.build b/Documentation/meson.build\n> > > index 8cf7775902f3..022770968fcf 100644\n> > > --- a/Documentation/meson.build\n> > > +++ b/Documentation/meson.build\n> > > @@ -193,6 +193,9 @@ if sphinx.found()\n> > >                    install_dir : doc_install_dir,\n> > >                    install_tag : 'doc')\n> > >  \n> > > +    meson.add_install_script('install-doxygen.sh', doc_install_dir,\n> > > +                             'api-html', 'internal-api-html')\n> > > +\n> > >      custom_target('documentation-linkcheck',\n> > >                    command : [sphinx, '-W', '-b', 'linkcheck',\n> > >                               '-c', sphinx_conf_dir,\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B2294C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 11:19:43 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A097A6936F;\n\tThu, 18 Sep 2025 13:19:42 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 72BFE62C3B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 13:19:40 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:ace3:d2c2:5eff:9cc5])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id A6376C6E;\n\tThu, 18 Sep 2025 13:18:20 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"MH8wSW7e\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758194300;\n\tbh=x6R1zaSLIolsOZwHEtt7M97Uv8dBWrPKQbVXRWgfUJE=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=MH8wSW7eciGF35UcjiD1EgHwZ0xm20jIlEHVkBP960PAJ19jH15o9jIAfBJdWdPqj\n\t7uW1NcljfNoUSazgQEvHjqnPI0EiQBftgGkPUkFX+5WP4mgj0jsE23CdlZFZSsqBvL\n\tzqMOP8RuDPr4PAMGn8K99k33LlW3rjTgXT8wcSTI=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250918082956.GF10145@pendragon.ideasonboard.com>","References":"<20250917201742.16406-1-laurent.pinchart@ideasonboard.com>\n\t<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>\n\t<175818021910.17312.6511880578495176271@localhost>\n\t<20250918082956.GF10145@pendragon.ideasonboard.com>","Subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","From":"Stefan Klug <stefan.klug@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Thu, 18 Sep 2025 13:19:37 +0200","Message-ID":"<175819437731.17312.15780346867150389081@localhost>","User-Agent":"alot/0.12.dev8+g2c003385c862.d20250602","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35893,"web_url":"https://patchwork.libcamera.org/comment/35893/","msgid":"<20250918130633.GI10145@pendragon.ideasonboard.com>","date":"2025-09-18T13:06:33","subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Sep 18, 2025 at 01:19:37PM +0200, Stefan Klug wrote:\n> Quoting Laurent Pinchart (2025-09-18 10:29:56)\n> > On Thu, Sep 18, 2025 at 09:23:39AM +0200, Stefan Klug wrote:\n> > > Hi Laurent,\n> > > \n> > > Thank you for the patch.\n> > > \n> > > Quoting Laurent Pinchart (2025-09-17 22:17:38)\n> > > > The libcamera documentation comprises two parts: pages generated by\n> > > > Sphinx into the Documentation/html/ directory within the build tree, and\n> > > > API reference documentation generated by Doxygen into\n> > > > Documentation/internal-api-html/ and Documentation/api-html/. The two\n> > > > parts are generated separately, but link to each other.\n> > > > \n> > > > From Sphinx to Doxygen, we use the doxylink extension for Sphinx to\n> > > > generate links to the Doxygen pages corresponding to API elements. The\n> > > > extension needs to be configured with the paths to the Doxygen\n> > > > documentation, which are set based on the html/, api-html/ and\n> > > > internal-api-html/ directories being placed side by side in the same\n> > > > parent directory.\n> > > > \n> > > > Furthermore, we also want to link to the API documentation from the\n> > > > Sphinx toctree. As toctrees can only link to pages within the Sphinx\n> > > > documents tree (or to http URLs), we have placeholder .rst documents for\n> > > > api-html and internal-api-html in the Sphinx documentation tree. Those\n> > > > generate the Documentation/html/internal-api-html/index.html and\n> > > > Documentation/html/api-html/index.html placeholder files in the build\n> > > > tree.\n> > > \n> > > We could mention the ../api-html path in these placeholders so that\n> > > someone reading the docs from the build dir gets a hint where to look.\n> > > \n> > > > The other way around, the API documentation's introduction pagelinks to\n> > > > Sphinx pages using relative paths. Those paths are hardcoded based on\n> > > > the api-html/ and internal-api-html/ directories being children of the\n> > > > html/ directory.\n> > > > \n> > > > This results in links being broken in different ways in the build tree,\n> > > > as well as in the installation directory: the toctree links direct to\n> > > > the placeholder pages within the html/ directory instead of the Doxygen\n> > > > documentation in sibling directories, and the Doxygen introduction links\n> > > > to Sphinx are simply broken. When publishing documentation on the\n> > > > website we work around those issues by patching several files and moving\n> > > \n> > > Do we really patch files? To my understanding we only do the move that\n> > > is also done by the install step now. Or am I missing something?\n> > \n> > We don't patch, indeed. We override the sphinx options with a custom\n> > conf.py. I'll change that in the commit message and write\n> > \n> > When publishing documentation on the website we work around those issues\n> > by overriding conf.py with a custom version and moving the api-html/ and\n> > internal-api-html/ directories to the html/ directory.\n> \n> Where does this override happen? I thought we only have a conf.py for\n> the website itself, but docs is now fully self contained (except\n> replicating the install step manually)?\n\nThat conf.py sets the doxylink configuration parameters with different\npaths than the conf.py in libcamera.\n\n> > > We could actually do a meson install --destdir= there.\n> > > \n> > > > the api-html/ and internal-api-html/ directories to the html/ directory.\n> > > > \n> > > > Fixing this is surprisingly difficult. The toctree links can't be\n> > > > changed to point to a path outside of the Sphinx document tree as this\n> > > > isn't supported by Sphinx. Using http URLs would link to the\n> > > > libcamera.org website inside of local documentation, which isn't\n> > > > acceptable. It may be possible to develop a Sphinx extension to patch\n> > > > the toctree after it gets parsed, but that would be complex and likely\n> > > > fragile. Modifying the install path of the Doxygen documentation to\n> > > > html/api-html/ and html/internal-api-html/ causes issues as the Sphinx\n> > > > documentation will then overwrite the Doxygen index.html files with the\n> > > > placeholder indexes. Creating symlinks from html/api-html/ to api-html/\n> > > > in the installation directory causes similar problems if 'meson install'\n> > > > is run twice. Creating the symlinks in the build directory (which was\n> > > > attempted with a custom Sphinx extension) is also a no-go: starting with\n> > > > meson v1.8.0, installing symlinks to directories causes an exception due\n> > > > to a bug in meson.\n> > > > \n> > > > The right solution is probably to investigate usage of the doxysphinx\n> > > > extension. As that's no small amount of work, let's start with a\n> > > > non-perfect but simple improvement: configure doxylink based on the\n> > > > api-html/ and internal-api-html/ directories being children of the\n> > > > Sphinx html/ documentation, and move those two API documentation\n> > > > directories to html/ during installation with a post-install script.\n> > > > This fixes links in the installation directory. Links in the build\n> > > > directory remain broken, but that is not a regression.\n> > > > \n> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > \n> > > Phew, that was a ride. Now the initial cp moved into the install step. I\n> > > like that workaround.\n> > > \n> > > Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > > \n> > > > ---\n> > > >  Documentation/conf.py.in         |  4 ++--\n> > > >  Documentation/install-doxygen.sh | 18 ++++++++++++++++++\n> > > >  Documentation/meson.build        |  3 +++\n> > > >  3 files changed, 23 insertions(+), 2 deletions(-)\n> > > >  create mode 100755 Documentation/install-doxygen.sh\n> > > > \n> > > > diff --git a/Documentation/conf.py.in b/Documentation/conf.py.in\n> > > > index 34fa3956f49e..2c75a75799e6 100644\n> > > > --- a/Documentation/conf.py.in\n> > > > +++ b/Documentation/conf.py.in\n> > > > @@ -75,11 +75,11 @@ pygments_style = None\n> > > >  doxylink = {\n> > > >      'doxy-pub': (\n> > > >          '@TOP_BUILDDIR@/Documentation/api-html/tagfile.xml',\n> > > > -        '../api-html/',\n> > > > +        'api-html/',\n> > > >      ),\n> > > >      'doxy-int': (\n> > > >          '@TOP_BUILDDIR@/Documentation/internal-api-html/tagfile.xml',\n> > > > -        '../internal-api-html/',\n> > > > +        'internal-api-html/',\n> > > >      ),\n> > > >  }\n> > > >  \n> > > > diff --git a/Documentation/install-doxygen.sh b/Documentation/install-doxygen.sh\n> > > > new file mode 100755\n> > > > index 000000000000..ea5a19dc8fda\n> > > > --- /dev/null\n> > > > +++ b/Documentation/install-doxygen.sh\n> > > > @@ -0,0 +1,18 @@\n> > > > +#!/bin/sh\n> > > > +# SPDX-License-Identifier: GPL-2.0-or-later\n> > > > +# Copyright (C) 2025, Ideas on Board Oy\n> > > > +#\n> > > > +# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > > +#\n> > > > +# Move Doxygen-generated API documentation to correct location\n> > > > +\n> > > > +doc_dir=\"${MESON_INSTALL_DESTDIR_PREFIX}/$1\"\n> > > > +shift\n> > > > +dirs=\"$*\"\n> > > > +\n> > > > +echo \"Moving API documentation\"\n> > > > +\n> > > > +for dir in $dirs ; do\n> > > > +       rm -r \"${doc_dir}/html/${dir}\"\n> > > > +       mv \"${doc_dir}/${dir}\" \"${doc_dir}/html/\"\n> > > > +done\n> > > > diff --git a/Documentation/meson.build b/Documentation/meson.build\n> > > > index 8cf7775902f3..022770968fcf 100644\n> > > > --- a/Documentation/meson.build\n> > > > +++ b/Documentation/meson.build\n> > > > @@ -193,6 +193,9 @@ if sphinx.found()\n> > > >                    install_dir : doc_install_dir,\n> > > >                    install_tag : 'doc')\n> > > >  \n> > > > +    meson.add_install_script('install-doxygen.sh', doc_install_dir,\n> > > > +                             'api-html', 'internal-api-html')\n> > > > +\n> > > >      custom_target('documentation-linkcheck',\n> > > >                    command : [sphinx, '-W', '-b', 'linkcheck',\n> > > >                               '-c', sphinx_conf_dir,","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6E3D3BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 13:07:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9CDAD6936A;\n\tThu, 18 Sep 2025 15:07:06 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5759162C3B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 15:07:03 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id EDE2C842;\n\tThu, 18 Sep 2025 15:05:42 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"iv6cHeAa\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758200743;\n\tbh=U/O1RLdxwSSEneMZclR6L+NLWltOD3U53HeDrV/KEmg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=iv6cHeAahMnc5TQTzZmMl2n8g3JI+XejnJJo3mfC1gLDHkmnJxuq7pdXkuSliMCwo\n\tPjpz0VS6YMmY5Jof0/zjM2u/f0HREa3N1rhiRXy4NJCe37tZxDygua5zRovN90zRNI\n\t0LhO4xw0FVXoGfAvPiv9Yse4yuPKjMZZq9KOEr2o=","Date":"Thu, 18 Sep 2025 16:06:33 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v3 07/10] Documentation: Improve Sphinx and Doxygen\n\tintegration","Message-ID":"<20250918130633.GI10145@pendragon.ideasonboard.com>","References":"<20250917201742.16406-1-laurent.pinchart@ideasonboard.com>\n\t<20250917201742.16406-8-laurent.pinchart@ideasonboard.com>\n\t<175818021910.17312.6511880578495176271@localhost>\n\t<20250918082956.GF10145@pendragon.ideasonboard.com>\n\t<175819437731.17312.15780346867150389081@localhost>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<175819437731.17312.15780346867150389081@localhost>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]