diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst
index 7e45cdb84b85..5aa09e90f419 100644
--- a/Documentation/guides/pipeline-handler.rst
+++ b/Documentation/guides/pipeline-handler.rst
@@ -151,13 +151,14 @@ integrates with the libcamera build system, and a *vivid.cpp* file that matches
 the name of the pipeline.
 
 In the *meson.build* file, add the *vivid.cpp* file as a build source for
-libcamera by adding it to the global meson ``libcamera_sources`` variable:
+libcamera by adding it to the global meson ``libcamera_internal_sources``
+variable:
 
 .. code-block:: none
 
    # SPDX-License-Identifier: CC0-1.0
 
-   libcamera_sources += files([
+   libcamera_internal_sources += files([
        'vivid.cpp',
    ])
 
diff --git a/Documentation/meson.build b/Documentation/meson.build
index 30d395234952..070420715bd1 100644
--- a/Documentation/meson.build
+++ b/Documentation/meson.build
@@ -31,12 +31,14 @@ if doxygen.found() and dot.found()
     doxygen_input = [
         doxyfile,
         libcamera_base_headers,
-        libcamera_base_sources,
+        libcamera_base_public_sources,
+        libcamera_base_internal_sources,
         libcamera_internal_headers,
         libcamera_ipa_headers,
         libcamera_ipa_interfaces,
         libcamera_public_headers,
-        libcamera_sources,
+        libcamera_public_sources,
+        libcamera_internal_sources,
         libipa_headers,
         libipa_sources,
     ]
diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build
index 4a228d335ba4..a742dfdfeb24 100644
--- a/src/libcamera/base/meson.build
+++ b/src/libcamera/base/meson.build
@@ -1,25 +1,28 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_base_sources = files([
-    'backtrace.cpp',
-    'class.cpp',
+libcamera_base_public_sources = files([
     'bound_method.cpp',
+    'class.cpp',
+    'flags.cpp',
+    'object.cpp',
+    'shared_fd.cpp',
+    'signal.cpp',
+    'unique_fd.cpp',
+])
+
+libcamera_base_internal_sources = files([
+    'backtrace.cpp',
     'event_dispatcher.cpp',
     'event_dispatcher_poll.cpp',
     'event_notifier.cpp',
     'file.cpp',
-    'flags.cpp',
     'log.cpp',
     'memfd.cpp',
     'message.cpp',
     'mutex.cpp',
-    'object.cpp',
     'semaphore.cpp',
-    'shared_fd.cpp',
-    'signal.cpp',
     'thread.cpp',
     'timer.cpp',
-    'unique_fd.cpp',
     'utils.cpp',
 ])
 
@@ -50,7 +53,11 @@ libcamera_base_deps = [
 libcamera_base_args = [ '-DLIBCAMERA_BASE_PRIVATE' ]
 
 libcamera_base_lib = shared_library('libcamera-base',
-                                    [libcamera_base_sources, libcamera_base_headers],
+                                    [
+                                        libcamera_base_public_sources,
+                                        libcamera_base_internal_sources,
+                                        libcamera_base_headers,
+                                    ],
                                     version : libcamera_version,
                                     soversion : libcamera_soversion,
                                     name_prefix : '',
diff --git a/src/libcamera/converter/meson.build b/src/libcamera/converter/meson.build
index 2aa72fe456a4..af1a80fec683 100644
--- a/src/libcamera/converter/meson.build
+++ b/src/libcamera/converter/meson.build
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
         'converter_v4l2_m2m.cpp'
 ])
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 89504cee1146..deffff356091 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -1,14 +1,26 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources = files([
-    'bayer_format.cpp',
-    'byte_stream_buffer.cpp',
+libcamera_public_sources = files([
     'camera.cpp',
-    'camera_controls.cpp',
-    'camera_lens.cpp',
     'camera_manager.cpp',
     'color_space.cpp',
     'controls.cpp',
+    'fence.cpp',
+    'framebuffer.cpp',
+    'framebuffer_allocator.cpp',
+    'geometry.cpp',
+    'orientation.cpp',
+    'pixel_format.cpp',
+    'request.cpp',
+    'stream.cpp',
+    'transform.cpp',
+])
+
+libcamera_internal_sources = files([
+    'bayer_format.cpp',
+    'byte_stream_buffer.cpp',
+    'camera_controls.cpp',
+    'camera_lens.cpp',
     'control_serializer.cpp',
     'control_validator.cpp',
     'converter.cpp',
@@ -16,11 +28,7 @@ libcamera_sources = files([
     'device_enumerator.cpp',
     'device_enumerator_sysfs.cpp',
     'dma_buf_allocator.cpp',
-    'fence.cpp',
     'formats.cpp',
-    'framebuffer.cpp',
-    'framebuffer_allocator.cpp',
-    'geometry.cpp',
     'ipa_controls.cpp',
     'ipa_data_serializer.cpp',
     'ipa_interface.cpp',
@@ -33,17 +41,12 @@ libcamera_sources = files([
     'mapped_framebuffer.cpp',
     'media_device.cpp',
     'media_object.cpp',
-    'orientation.cpp',
     'pipeline_handler.cpp',
-    'pixel_format.cpp',
     'process.cpp',
     'pub_key.cpp',
-    'request.cpp',
     'shared_mem_object.cpp',
     'source_paths.cpp',
-    'stream.cpp',
     'sysfs.cpp',
-    'transform.cpp',
     'v4l2_device.cpp',
     'v4l2_pixelformat.cpp',
     'v4l2_subdevice.cpp',
@@ -51,9 +54,9 @@ libcamera_sources = files([
     'yaml_parser.cpp',
 ])
 
-libcamera_sources += libcamera_public_headers
-libcamera_sources += libcamera_generated_ipa_headers
-libcamera_sources += libcamera_tracepoint_header
+libcamera_public_sources += libcamera_public_headers
+libcamera_internal_sources += libcamera_generated_ipa_headers
+libcamera_internal_sources += libcamera_tracepoint_header
 
 includes = [
     libcamera_includes,
@@ -104,14 +107,14 @@ endif
 if liblttng.found()
     tracing_enabled = true
     config_h.set('HAVE_TRACING', 1)
-    libcamera_sources += files(['tracepoints.cpp'])
+    libcamera_internal_sources += files(['tracepoints.cpp'])
 else
     tracing_enabled = false
 endif
 
 if libudev.found()
     config_h.set('HAVE_LIBUDEV', 1)
-    libcamera_sources += files([
+    libcamera_internal_sources += files([
         'device_enumerator_udev.cpp',
     ])
 endif
@@ -152,7 +155,7 @@ foreach mode, input_files : controls_mode_files
                                                 '-r', ranges_file, '@INPUT@'])
 endforeach
 
-libcamera_sources += control_sources
+libcamera_public_sources += control_sources
 
 gen_version = meson.project_source_root() / 'utils' / 'gen-version.sh'
 
@@ -163,7 +166,7 @@ version_cpp = vcs_tag(command : [gen_version, meson.project_build_root(), meson.
                       output : 'version.cpp',
                       fallback : meson.project_version())
 
-libcamera_sources += version_cpp
+libcamera_public_sources += version_cpp
 
 if ipa_sign_module
     ipa_pub_key_cpp = custom_target('ipa_pub_key_cpp',
@@ -171,7 +174,7 @@ if ipa_sign_module
                                     output : 'ipa_pub_key.cpp',
                                     command : [gen_ipa_pub_key, '@INPUT@', '@OUTPUT@'])
 
-    libcamera_sources += ipa_pub_key_cpp
+    libcamera_internal_sources += ipa_pub_key_cpp
 endif
 
 libcamera_deps += [
@@ -191,7 +194,10 @@ libcamera_deps += [
 # for the presence or abscence of the dynamic tag.
 
 libcamera = shared_library('libcamera',
-                           libcamera_sources,
+                           [
+                               libcamera_public_sources,
+                               libcamera_internal_sources,
+                           ],
                            version : libcamera_version,
                            soversion : libcamera_soversion,
                            name_prefix : '',
diff --git a/src/libcamera/pipeline/imx8-isi/meson.build b/src/libcamera/pipeline/imx8-isi/meson.build
index ffd0ce54ce92..b369b03141cb 100644
--- a/src/libcamera/pipeline/imx8-isi/meson.build
+++ b/src/libcamera/pipeline/imx8-isi/meson.build
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'imx8-isi.cpp'
 ])
diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build
index a1b0b31ac5bc..f2904b4a8929 100644
--- a/src/libcamera/pipeline/ipu3/meson.build
+++ b/src/libcamera/pipeline/ipu3/meson.build
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'cio2.cpp',
     'frames.cpp',
     'imgu.cpp',
diff --git a/src/libcamera/pipeline/mali-c55/meson.build b/src/libcamera/pipeline/mali-c55/meson.build
index 30fd29b928d5..eba8e5a39054 100644
--- a/src/libcamera/pipeline/mali-c55/meson.build
+++ b/src/libcamera/pipeline/mali-c55/meson.build
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'mali-c55.cpp'
 ])
diff --git a/src/libcamera/pipeline/rkisp1/meson.build b/src/libcamera/pipeline/rkisp1/meson.build
index cad66535c25f..d21a6ef96bef 100644
--- a/src/libcamera/pipeline/rkisp1/meson.build
+++ b/src/libcamera/pipeline/rkisp1/meson.build
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'rkisp1.cpp',
     'rkisp1_path.cpp',
 ])
diff --git a/src/libcamera/pipeline/rpi/common/meson.build b/src/libcamera/pipeline/rpi/common/meson.build
index 8fb7e823279d..b2b1a0a61284 100644
--- a/src/libcamera/pipeline/rpi/common/meson.build
+++ b/src/libcamera/pipeline/rpi/common/meson.build
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'delayed_controls.cpp',
     'pipeline_base.cpp',
     'rpi_stream.cpp',
diff --git a/src/libcamera/pipeline/rpi/vc4/meson.build b/src/libcamera/pipeline/rpi/vc4/meson.build
index 386e2296785a..9b37c2f089f2 100644
--- a/src/libcamera/pipeline/rpi/vc4/meson.build
+++ b/src/libcamera/pipeline/rpi/vc4/meson.build
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'vc4.cpp',
 ])
 
diff --git a/src/libcamera/pipeline/simple/meson.build b/src/libcamera/pipeline/simple/meson.build
index 42b0896dff8b..dda3de9782e4 100644
--- a/src/libcamera/pipeline/simple/meson.build
+++ b/src/libcamera/pipeline/simple/meson.build
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'simple.cpp',
 ])
diff --git a/src/libcamera/pipeline/uvcvideo/meson.build b/src/libcamera/pipeline/uvcvideo/meson.build
index a3c2efd424bf..a3a91074f916 100644
--- a/src/libcamera/pipeline/uvcvideo/meson.build
+++ b/src/libcamera/pipeline/uvcvideo/meson.build
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'uvcvideo.cpp',
 ])
diff --git a/src/libcamera/pipeline/vimc/meson.build b/src/libcamera/pipeline/vimc/meson.build
index 290eefb5d076..868e2546a087 100644
--- a/src/libcamera/pipeline/vimc/meson.build
+++ b/src/libcamera/pipeline/vimc/meson.build
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'vimc.cpp',
 ])
diff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build
index 00ae5a8ffa47..d7de518a0549 100644
--- a/src/libcamera/proxy/meson.build
+++ b/src/libcamera/proxy/meson.build
@@ -15,5 +15,5 @@ foreach mojom : ipa_mojoms
                               './' + '@INPUT@'
                           ])
 
-    libcamera_sources += proxy
+    libcamera_internal_sources += proxy
 endforeach
diff --git a/src/libcamera/sensor/meson.build b/src/libcamera/sensor/meson.build
index bf4b131a94b1..61234e950d04 100644
--- a/src/libcamera/sensor/meson.build
+++ b/src/libcamera/sensor/meson.build
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: CC0-1.0
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'camera_sensor.cpp',
     'camera_sensor_properties.cpp',
 ])
diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build
index f7c66e28f9b9..aac7eda7b5b3 100644
--- a/src/libcamera/software_isp/meson.build
+++ b/src/libcamera/software_isp/meson.build
@@ -7,7 +7,7 @@ if not softisp_enabled
     subdir_done()
 endif
 
-libcamera_sources += files([
+libcamera_internal_sources += files([
     'debayer.cpp',
     'debayer_cpu.cpp',
     'software_isp.cpp',
