diff --git a/.gitlab-ci/build-libcamera-subproject.sh b/.gitlab-ci/build-libcamera-subproject.sh
new file mode 100755
index 0000000..ae59ac3
--- /dev/null
+++ b/.gitlab-ci/build-libcamera-subproject.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: © 2025 Ideas on Board Oy
+#
+# Build libcamera as a meson subproject
+
+set -e
+
+source "$(dirname "$0")/lib.sh"
+source "$(dirname "$0")/build-libcamera-common.sh"
+
+PROJECT_ROOT=$(mktemp -d ./subproject-test.XXXXXX)
+
+libcamera_setup_as_subproject() {
+	echo "Setting up libcamera build with meson options $MESON_OPTIONS"
+
+	mkdir -p "$PROJECT_ROOT/subprojects"
+	ln -s ../../ "$PROJECT_ROOT/subprojects/libcamera"
+
+	# Convert options suitable for the `default_options` parameter of `subproject()`
+	echo "$MESON_OPTIONS" \
+		| sed 's/-D[[:space:]]*//g' \
+		| tr ' ' '\n' \
+		| sed "s/'/\"/g" \
+		| sed "s/^\(.*\)$/\t\t'\1',/" \
+		> "$PROJECT_ROOT/meson-options"
+
+	cat > "$PROJECT_ROOT/meson.build" <<EOF
+project('libcamera-as-subproject-test')
+subproject(
+	'libcamera',
+	default_options : [
+EOF
+	cat "$PROJECT_ROOT/meson-options" >> "$PROJECT_ROOT/meson.build"
+	cat >> "$PROJECT_ROOT/meson.build" <<EOF
+	],
+)
+EOF
+
+	cat "$PROJECT_ROOT/meson.build"
+
+	meson setup build "$PROJECT_ROOT" \
+		--wrap-mode=nofallback \
+		-D buildtype=$BUILD_TYPE
+}
+
+libcamera_build_as_subproject() {
+	echo "Building libcamera as subproject"
+
+	meson compile \
+		-C build \
+		-j$BUILD_CONCURRENT_JOBS \
+		--ninja-args="-k0"
+}
+
+run libcamera_install_pkgs
+run libcamera_setup_as_subproject
+run libcamera_build_as_subproject collapsed
diff --git a/gitlab-ci.yml b/gitlab-ci.yml
index c751973..fd837f5 100644
--- a/gitlab-ci.yml
+++ b/gitlab-ci.yml
@@ -212,6 +212,30 @@ build-full:debian:12:
       - ARCH: armhf
       - ARCH: arm64

+build-full:debian:12:as-subproject:
+  extends:
+    - .fdo.distribution-image@debian
+    - .libcamera-ci.debian:12
+    - .libcamera-ci.scripts
+  variables:
+    BUILD_TYPE: debug
+    MESON_OPTIONS: >-
+      ${MESON_ALL_OPTIONS}
+      -D documentation=enabled
+  needs:
+    - job: container-debian:12
+      artifacts: false
+  stage: build
+  script:
+    - $CI_PROJECT_DIR/.gitlab-ci/build-libcamera-subproject.sh
+  artifacts:
+    when: always
+    expire_in: 1 week
+    paths:
+      - build/meson-logs/
+      - build/meson-intro/
+      - build/build.ninja
+
 build-full:debian:13:
   extends:
     - .libcamera-ci.debian:13
