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)
 
