{"id":24160,"url":"https://patchwork.libcamera.org/api/1.1/patches/24160/?format=json","web_url":"https://patchwork.libcamera.org/patch/24160/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20250819012402.8395-2-laurent.pinchart@ideasonboard.com>","date":"2025-08-19T01:23:59","name":"[v3,1/3] py: libcamera: Improve python binding installation","commit_ref":"91365356bdcc7aa2525d871c12f35320a805a37a","pull_url":null,"state":"accepted","archived":false,"hash":"5d39189ab8dbeed6ad03878e612e1e130ba6d927","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/1.1/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/24160/mbox/","series":[{"id":5393,"url":"https://patchwork.libcamera.org/api/1.1/series/5393/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5393","date":"2025-08-19T01:23:58","name":"py: Improve native and cross-compilation of Python bindings","version":3,"mbox":"https://patchwork.libcamera.org/series/5393/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/24160/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/24160/checks/","tags":{},"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 3142BBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 19 Aug 2025 01:24:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7AA516926D;\n\tTue, 19 Aug 2025 03:24:29 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F1C53613C5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 Aug 2025 03:24:25 +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 5D2FBC6D;\n\tTue, 19 Aug 2025 03:23:28 +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=\"Ps00IPT3\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1755566608;\n\tbh=HFVJ7KHekzH6I2S+XJMkq2TsCTyNeUVcVZws6ggkezg=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Ps00IPT3c372dgCpHP3yk9lTEVkJeF0Q6EsREMaa4UHHQOg6g3Ab3k9Ig0hzCANd9\n\t3BircFuXuE86PoerqotBOgwTUVqFU2b8zStC+UqnsK/JMqI8ftvYiN8CAKI8GOkH5q\n\tAa4WQrNBI1R4xZJQX7qmLKc5H+bPO51Hj6Wrau/g=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"William Vinnicombe <william.vinnicombe@raspberrypi.com>,\n\tTomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Subject":"[PATCH v3 1/3] py: libcamera: Improve python binding installation","Date":"Tue, 19 Aug 2025 04:23:59 +0300","Message-ID":"<20250819012402.8395-2-laurent.pinchart@ideasonboard.com>","X-Mailer":"git-send-email 2.49.1","In-Reply-To":"<20250819012402.8395-1-laurent.pinchart@ideasonboard.com>","References":"<20250819012402.8395-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","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>"},"content":"From: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n\nThe existing meson.build file installs the bindings to a manually\nconstructed directory that is not included in the Python path in most\ndistributions. For instance, on a  Debian 12 system, the modules is\nintalled in /usr/lib/x86_64-linux-gnu/python3.11/site-packages/, while\nthe Python interpreter looks for site packages in\n/usr/lib/python3/dist-packages/.\n\nIt also always builds the bindings using the system Python, as it\nsearches for the Python library using the standard dependency()\nfunction. This prevents build the Python bindings for a different\ninterpreter version without changing the system default interpreter.\n\nModify the build process to use the meson python module to build the\nPython bindings targets, so it installs them to the correct directories\nfor Python. This also allows specifying a different target Python\ninterpreter through the '[binaries]' section of a meson native file.\n\nThe behaviour is not changed for cross-compilation, as the meson python\nmodule has known issues in that case.\n\nSigned-off-by: William Vinnicombe <william.vinnicombe@raspberrypi.com>\nCo-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/py/libcamera/meson.build | 41 ++++++++++++++++++++++++------------\n src/py/meson.build           | 13 +++++++++++-\n test/py/meson.build          |  3 ---\n 3 files changed, 40 insertions(+), 17 deletions(-)","diff":"diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build\nindex 33ab65798559..fe22ffd2f70b 100644\n--- a/src/py/libcamera/meson.build\n+++ b/src/py/libcamera/meson.build\n@@ -57,16 +57,35 @@ pycamera_args = [\n     '-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT',\n ]\n \n-destdir = get_option('libdir') / ('python' + py3_dep.version()) / 'site-packages' / 'libcamera'\n+if meson.is_cross_build()\n+    # Meson doesn't correctly support cross-compilation through the python\n+    # module. There's work in progress to fix this, based on PEP 739\n+    # (https://github.com/mesonbuild/meson/pull/14657). While waiting for this\n+    # to become available, work around the issue by using shared_module().\n+    destdir = get_option('libdir') / ('python' + py3_dep.version()) / 'site-packages' / 'libcamera'\n \n-pycamera = shared_module('_libcamera',\n-                         pycamera_sources,\n-                         install : true,\n-                         install_dir : destdir,\n-                         install_tag : 'python-runtime',\n-                         name_prefix : '',\n-                         dependencies : pycamera_deps,\n-                         cpp_args : pycamera_args)\n+    pycamera = shared_module('_libcamera',\n+                             pycamera_sources,\n+                             install : true,\n+                             install_dir : destdir,\n+                             install_tag : 'python-runtime',\n+                             name_prefix : '',\n+                             dependencies : pycamera_deps,\n+                             cpp_args : pycamera_args)\n+    install_data(['__init__.py'],\n+                 install_dir : destdir,\n+                 install_tag : 'python-runtime')\n+else\n+    pycamera = py3.extension_module('_libcamera',\n+                                    pycamera_sources,\n+                                    install : true,\n+                                    subdir : 'libcamera',\n+                                    dependencies : pycamera_deps,\n+                                    cpp_args : pycamera_args)\n+    py3.install_sources(['__init__.py'],\n+                        subdir : 'libcamera',\n+                        pure : false)\n+endif\n \n # Create symlinks from the build dir to the source dir so that we can use the\n # Python module directly from the build dir.\n@@ -79,10 +98,6 @@ run_command('ln', '-fsrT', meson.current_source_dir() / 'utils',\n             meson.current_build_dir() / 'utils',\n             check : true)\n \n-install_data(['__init__.py'],\n-             install_dir : destdir,\n-             install_tag : 'python-runtime')\n-\n # \\todo Generate stubs when building. See https://peps.python.org/pep-0484/#stub-files\n # Note: Depends on pybind11-stubgen. To generate pylibcamera stubs:\n # $ PYTHONPATH=build/src/py pybind11-stubgen --no-setup-py -o build/src/py libcamera\ndiff --git a/src/py/meson.build b/src/py/meson.build\nindex 9228069711be..24102f83d2e1 100644\n--- a/src/py/meson.build\n+++ b/src/py/meson.build\n@@ -1,6 +1,17 @@\n # SPDX-License-Identifier: CC0-1.0\n \n-py3_dep = dependency('python3', required : get_option('pycamera'))\n+if meson.is_cross_build()\n+    py3_dep = dependency('python3', required : get_option('pycamera'))\n+else\n+    py3 = import('python').find_installation('python3', required : get_option('pycamera'))\n+    if not py3.found()\n+        pycamera_enabled = false\n+        subdir_done()\n+    endif\n+\n+    py3_dep = py3.dependency(required : get_option('pycamera'))\n+endif\n+\n pybind11_dep = dependency('pybind11', required : get_option('pycamera'))\n \n pycamera_enabled = py3_dep.found() and pybind11_dep.found()\ndiff --git a/test/py/meson.build b/test/py/meson.build\nindex b922e8578c29..d014aac4573e 100644\n--- a/test/py/meson.build\n+++ b/test/py/meson.build\n@@ -15,9 +15,6 @@ endif\n \n py_env = environment()\n \n-pymod = import('python')\n-py3 = pymod.find_installation('python3')\n-\n pypathdir = meson.project_build_root() / 'src' / 'py'\n py_env.append('PYTHONPATH', pypathdir)\n \n","prefixes":["v3","1/3"]}