diff --git a/include/libcamera/ipa/meson.build b/include/libcamera/ipa/meson.build
index 96fca42cc0b8..bf55e124e97e 100644
--- a/include/libcamera/ipa/meson.build
+++ b/include/libcamera/ipa/meson.build
@@ -26,7 +26,8 @@ ipa_mojom_core = custom_target(core_mojom_file.split('.')[0] + '_mojom_module',
                                    '--output-root', meson.project_build_root(),
                                    '--input-root', meson.project_source_root(),
                                    '--mojoms', '@INPUT@'
-                               ])
+                               ],
+                               env : py_build_env)
 
 # core_ipa_interface.h
 libcamera_ipa_headers += custom_target('core_ipa_interface_h',
@@ -42,7 +43,8 @@ libcamera_ipa_headers += custom_target('core_ipa_interface_h',
                       '--libcamera_generate_core_header',
                       '--libcamera_output_path=@OUTPUT@',
                       './' +'@INPUT@'
-                  ])
+                  ],
+                  env : py_build_env)
 
 # core_ipa_serializer.h
 libcamera_ipa_headers += custom_target('core_ipa_serializer_h',
@@ -56,7 +58,8 @@ libcamera_ipa_headers += custom_target('core_ipa_serializer_h',
                       '--libcamera_generate_core_serializer',
                       '--libcamera_output_path=@OUTPUT@',
                       './' +'@INPUT@'
-                  ])
+                  ],
+                  env : py_build_env)
 
 # Mapping from pipeline handler name to mojom file
 pipeline_ipa_mojom_mapping = {
@@ -99,7 +102,8 @@ foreach pipeline, file : pipeline_ipa_mojom_mapping
                               '--output-root', meson.project_build_root(),
                               '--input-root', meson.project_source_root(),
                               '--mojoms', '@INPUT@'
-                          ])
+                          ],
+                          env : py_build_env)
 
     # {interface}_ipa_interface.h
     header = custom_target(name + '_ipa_interface_h',
@@ -115,7 +119,8 @@ foreach pipeline, file : pipeline_ipa_mojom_mapping
                                '--libcamera_generate_header',
                                '--libcamera_output_path=@OUTPUT@',
                                './' +'@INPUT@'
-                           ])
+                           ],
+                           env : py_build_env)
 
     # {interface}_ipa_serializer.h
     serializer = custom_target(name + '_ipa_serializer_h',
@@ -129,7 +134,8 @@ foreach pipeline, file : pipeline_ipa_mojom_mapping
                                    '--libcamera_generate_serializer',
                                    '--libcamera_output_path=@OUTPUT@',
                                    './' +'@INPUT@'
-                               ])
+                               ],
+                               env : py_build_env)
 
     # {interface}_ipa_proxy.h
     proxy_header = custom_target(name + '_proxy_h',
@@ -143,7 +149,8 @@ foreach pipeline, file : pipeline_ipa_mojom_mapping
                                      '--libcamera_generate_proxy_h',
                                      '--libcamera_output_path=@OUTPUT@',
                                      './' +'@INPUT@'
-                                 ])
+                                 ],
+                                 env : py_build_env)
 
     ipa_mojoms += {
         'name': name,
diff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build
index d7de518a0549..8bd1b135d0f5 100644
--- a/src/libcamera/proxy/meson.build
+++ b/src/libcamera/proxy/meson.build
@@ -13,7 +13,8 @@ foreach mojom : ipa_mojoms
                               '--libcamera_generate_proxy_cpp',
                               '--libcamera_output_path=@OUTPUT@',
                               './' + '@INPUT@'
-                          ])
+                          ],
+                          env : py_build_env)
 
     libcamera_internal_sources += proxy
 endforeach
diff --git a/src/libcamera/proxy/worker/meson.build b/src/libcamera/proxy/worker/meson.build
index b5ab9794c622..8c54a2e206a5 100644
--- a/src/libcamera/proxy/worker/meson.build
+++ b/src/libcamera/proxy/worker/meson.build
@@ -15,7 +15,8 @@ foreach mojom : ipa_mojoms
                                '--libcamera_generate_proxy_worker',
                                '--libcamera_output_path=@OUTPUT@',
                                './' + '@INPUT@'
-                           ])
+                           ],
+                           env : py_build_env)
 
     proxy = executable(mojom['name'] + '_ipa_proxy', worker,
                        install : true,
diff --git a/test/serialization/generated_serializer/include/libcamera/ipa/meson.build b/test/serialization/generated_serializer/include/libcamera/ipa/meson.build
index 6f8794c188a3..ae08e9bee6b9 100644
--- a/test/serialization/generated_serializer/include/libcamera/ipa/meson.build
+++ b/test/serialization/generated_serializer/include/libcamera/ipa/meson.build
@@ -9,7 +9,8 @@ mojom = custom_target('test_mojom_module',
                           '--output-root', meson.project_build_root(),
                           '--input-root', meson.project_source_root(),
                           '--mojoms', '@INPUT@'
-                      ])
+                      ],
+                      env : py_build_env)
 
 # test_ipa_interface.h
 generated_test_header = custom_target('test_ipa_interface_h',
@@ -23,7 +24,8 @@ generated_test_header = custom_target('test_ipa_interface_h',
                            '--libcamera_generate_header',
                            '--libcamera_output_path=@OUTPUT@',
                            './' +'@INPUT@'
-                       ])
+                       ],
+                       env : py_build_env)
 
 # test_ipa_serializer.h
 generated_test_serializer = custom_target('test_ipa_serializer_h',
@@ -37,4 +39,5 @@ generated_test_serializer = custom_target('test_ipa_serializer_h',
                                '--libcamera_generate_serializer',
                                '--libcamera_output_path=@OUTPUT@',
                                './' +'@INPUT@'
-                           ])
+                           ],
+                           env : py_build_env)
diff --git a/utils/codegen/ipc/generate.py b/utils/codegen/ipc/generate.py
index c2b3fcb72e1f..dfbe659bc0ca 100755
--- a/utils/codegen/ipc/generate.py
+++ b/utils/codegen/ipc/generate.py
@@ -9,9 +9,6 @@
 import os
 import sys
 
-# TODO set sys.pycache_prefix for >= python3.8
-sys.dont_write_bytecode = True
-
 sys.path.insert(0, f'{os.path.dirname(__file__)}/mojo/public/tools/bindings')
 
 import mojo.public.tools.bindings.mojom_bindings_generator as generator
diff --git a/utils/codegen/ipc/meson.build b/utils/codegen/ipc/meson.build
index 973a5417dc99..f77bf32497ba 100644
--- a/utils/codegen/ipc/meson.build
+++ b/utils/codegen/ipc/meson.build
@@ -13,6 +13,7 @@ mojom_docs_extractor = find_program('./extract-docs.py')
 mojom_templates = custom_target('mojom_templates',
                                 input : mojom_template_files,
                                 output : 'libcamera_templates.zip',
-                                command : [mojom_generator, '-o', '@OUTDIR@', 'precompile'])
+                                command : [mojom_generator, '-o', '@OUTDIR@', 'precompile'],
+                                env : py_build_env)
 
 mojom_templates_dir = meson.current_build_dir()
diff --git a/utils/codegen/ipc/parser.py b/utils/codegen/ipc/parser.py
index cb5608b7c165..8e70322d1bdb 100755
--- a/utils/codegen/ipc/parser.py
+++ b/utils/codegen/ipc/parser.py
@@ -9,9 +9,6 @@
 import os
 import sys
 
-# TODO set sys.pycache_prefix for >= python3.8
-sys.dont_write_bytecode = True
-
 # Make sure that mojom_parser.py can import mojom
 sys.path.insert(0, f'{os.path.dirname(__file__)}/mojo/public/tools/mojom')
 
diff --git a/utils/codegen/meson.build b/utils/codegen/meson.build
index 7dd312e16559..fb2196ee0d20 100644
--- a/utils/codegen/meson.build
+++ b/utils/codegen/meson.build
@@ -2,6 +2,10 @@
 
 ## Code generation
 
+py_build_env = environment()
+# \todo Investigate usage of PYTHONPYCACHEPREFIX for Python >= 3.8
+py_build_env.set('PYTHONDONTWRITEBYTECODE', '1')
+
 py_modules += ['jinja2', 'yaml']
 
 gen_controls = files('gen-controls.py')
