diff --git a/meson.build b/meson.build
index c6e6a934e54e..a1e455249b0d 100644
--- a/meson.build
+++ b/meson.build
@@ -24,6 +24,7 @@ libcamera_version = libcamera_git_version.split('+')[0]
 
 # Configure the build environment.
 cc = meson.get_compiler('c')
+cxx = meson.get_compiler('cpp')
 config_h = configuration_data()
 
 if cc.has_header_symbol('execinfo.h', 'backtrace')
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 1b69bc0dee54..ac6f597c6188 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -93,7 +93,7 @@ version_cpp = vcs_tag(command : [gen_version, meson.build_root()],
 libcamera_sources += version_cpp
 
 libcamera_deps = [
-    cc.find_library('atomic', required: false),
+    libatomic_dep,
     cc.find_library('dl'),
     libudev,
     dependency('threads'),
diff --git a/src/meson.build b/src/meson.build
index d818d8b86d93..abf755936f2b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,3 +1,20 @@
+# On some platforms gcc doesn't provide built-ins for atomic operations,
+# explicit linking against libatomic is required.
+if cxx.links('''
+    #include <atomic>
+    #include <cstdint>
+    int main(void)
+    {
+        std::atomic<std::uint32_t> u32(0);
+        std::atomic<std::uint64_t> u64(0);
+        return u32.load() + u64.load();
+    }
+''')
+    libatomic_dep = dependency('', required : false)
+else
+    libatomic_dep = cc.find_library('atomic')
+endif
+
 if get_option('android')
     subdir('android')
 endif
