[v3,1/3] py: libcamera: Improve python binding installation
diff mbox series

Message ID 20250819012402.8395-2-laurent.pinchart@ideasonboard.com
State Accepted
Commit 91365356bdcc7aa2525d871c12f35320a805a37a
Headers show
Series
  • py: Improve native and cross-compilation of Python bindings
Related show

Commit Message

Laurent Pinchart Aug. 19, 2025, 1:23 a.m. UTC
From: William Vinnicombe <william.vinnicombe@raspberrypi.com>

The existing meson.build file installs the bindings to a manually
constructed directory that is not included in the Python path in most
distributions. For instance, on a  Debian 12 system, the modules is
intalled in /usr/lib/x86_64-linux-gnu/python3.11/site-packages/, while
the Python interpreter looks for site packages in
/usr/lib/python3/dist-packages/.

It also always builds the bindings using the system Python, as it
searches for the Python library using the standard dependency()
function. This prevents build the Python bindings for a different
interpreter version without changing the system default interpreter.

Modify the build process to use the meson python module to build the
Python bindings targets, so it installs them to the correct directories
for Python. This also allows specifying a different target Python
interpreter through the '[binaries]' section of a meson native file.

The behaviour is not changed for cross-compilation, as the meson python
module has known issues in that case.

Signed-off-by: William Vinnicombe <william.vinnicombe@raspberrypi.com>
Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/py/libcamera/meson.build | 41 ++++++++++++++++++++++++------------
 src/py/meson.build           | 13 +++++++++++-
 test/py/meson.build          |  3 ---
 3 files changed, 40 insertions(+), 17 deletions(-)

Patch
diff mbox series

diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
index 33ab65798559..fe22ffd2f70b 100644
--- a/src/py/libcamera/meson.build
+++ b/src/py/libcamera/meson.build
@@ -57,16 +57,35 @@  pycamera_args = [
     '-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT',
 ]
 
-destdir = get_option('libdir') / ('python' + py3_dep.version()) / 'site-packages' / 'libcamera'
+if meson.is_cross_build()
+    # Meson doesn't correctly support cross-compilation through the python
+    # module. There's work in progress to fix this, based on PEP 739
+    # (https://github.com/mesonbuild/meson/pull/14657). While waiting for this
+    # to become available, work around the issue by using shared_module().
+    destdir = get_option('libdir') / ('python' + py3_dep.version()) / 'site-packages' / 'libcamera'
 
-pycamera = shared_module('_libcamera',
-                         pycamera_sources,
-                         install : true,
-                         install_dir : destdir,
-                         install_tag : 'python-runtime',
-                         name_prefix : '',
-                         dependencies : pycamera_deps,
-                         cpp_args : pycamera_args)
+    pycamera = shared_module('_libcamera',
+                             pycamera_sources,
+                             install : true,
+                             install_dir : destdir,
+                             install_tag : 'python-runtime',
+                             name_prefix : '',
+                             dependencies : pycamera_deps,
+                             cpp_args : pycamera_args)
+    install_data(['__init__.py'],
+                 install_dir : destdir,
+                 install_tag : 'python-runtime')
+else
+    pycamera = py3.extension_module('_libcamera',
+                                    pycamera_sources,
+                                    install : true,
+                                    subdir : 'libcamera',
+                                    dependencies : pycamera_deps,
+                                    cpp_args : pycamera_args)
+    py3.install_sources(['__init__.py'],
+                        subdir : 'libcamera',
+                        pure : false)
+endif
 
 # Create symlinks from the build dir to the source dir so that we can use the
 # Python module directly from the build dir.
@@ -79,10 +98,6 @@  run_command('ln', '-fsrT', meson.current_source_dir() / 'utils',
             meson.current_build_dir() / 'utils',
             check : true)
 
-install_data(['__init__.py'],
-             install_dir : destdir,
-             install_tag : 'python-runtime')
-
 # \todo Generate stubs when building. See https://peps.python.org/pep-0484/#stub-files
 # Note: Depends on pybind11-stubgen. To generate pylibcamera stubs:
 # $ PYTHONPATH=build/src/py pybind11-stubgen --no-setup-py -o build/src/py libcamera
diff --git a/src/py/meson.build b/src/py/meson.build
index 9228069711be..24102f83d2e1 100644
--- a/src/py/meson.build
+++ b/src/py/meson.build
@@ -1,6 +1,17 @@ 
 # SPDX-License-Identifier: CC0-1.0
 
-py3_dep = dependency('python3', required : get_option('pycamera'))
+if meson.is_cross_build()
+    py3_dep = dependency('python3', required : get_option('pycamera'))
+else
+    py3 = import('python').find_installation('python3', required : get_option('pycamera'))
+    if not py3.found()
+        pycamera_enabled = false
+        subdir_done()
+    endif
+
+    py3_dep = py3.dependency(required : get_option('pycamera'))
+endif
+
 pybind11_dep = dependency('pybind11', required : get_option('pycamera'))
 
 pycamera_enabled = py3_dep.found() and pybind11_dep.found()
diff --git a/test/py/meson.build b/test/py/meson.build
index b922e8578c29..d014aac4573e 100644
--- a/test/py/meson.build
+++ b/test/py/meson.build
@@ -15,9 +15,6 @@  endif
 
 py_env = environment()
 
-pymod = import('python')
-py3 = pymod.find_installation('python3')
-
 pypathdir = meson.project_build_root() / 'src' / 'py'
 py_env.append('PYTHONPATH', pypathdir)