diff --git a/scripts/ci/jobs/code-quality.yml b/scripts/ci/jobs/code-quality.yml
index dde4ce5be076c2c3bce0882da99272d39766d50d..d7f4021b5c68c2b5fe3b7a3645b87b59b3a0f6d7 100644
--- a/scripts/ci/jobs/code-quality.yml
+++ b/scripts/ci/jobs/code-quality.yml
@@ -1,18 +1,18 @@
 cppcheck:
   stage: check
   image: $CONTAINER_GCC_IMAGE
-  needs: ["pre commit"]
+  needs: ["pre commit", meta]
   before_script:
     - mkdir -p build
     - cd build
-  script: >-
-    cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGS_USE_CONAN=OFF \
+  script:
+    - >
+      cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGS_USE_CONAN=OFF
       -DOGS_USE_UNITY_BUILDS=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-    bash cppcheck.sh
+    - bash cppcheck.sh
   artifacts:
     reports:
       codequality: build/cppcheck.json
-    expire_in: 1 week
 
 # Disabled, see !3053
 .code_quality:
diff --git a/scripts/cmake/CppCheck.cmake b/scripts/cmake/CppCheck.cmake
index a960a96ae0cb8e5882c4aec308b8ba6503070bf1..487f3e871d901c0d5f370f5ff8a682c0c62d19af 100644
--- a/scripts/cmake/CppCheck.cmake
+++ b/scripts/cmake/CppCheck.cmake
@@ -2,6 +2,12 @@ if(NOT CPPCHECK_TOOL_PATH)
     return()
 endif()
 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CPPCHECK_PARALLEL 4)
+if(DEFINED ENV{CMAKE_BUILD_PARALLEL_LEVEL})
+    set(CPPCHECK_PARALLEL $ENV{CMAKE_BUILD_PARALLEL_LEVEL})
+elseif(DEFINED CMAKE_BUILD_PARALLEL_LEVEL)
+    set(CPPCHECK_PARALLEL ${CMAKE_BUILD_PARALLEL_LEVEL})
+endif()
 configure_file(${PROJECT_SOURCE_DIR}/scripts/test/cppcheck.in.sh ${PROJECT_BINARY_DIR}/cppcheck.sh)
 
 if(DEFINED ENV{NUM_THREADS})
diff --git a/scripts/test/cppcheck.in.sh b/scripts/test/cppcheck.in.sh
index 72a922ed7113d0564c7d75e16e313bd2aaf5b2e8..c5e6f8485a766fbe9970017b3855e4b49757ad34 100644
--- a/scripts/test/cppcheck.in.sh
+++ b/scripts/test/cppcheck.in.sh
@@ -6,12 +6,11 @@ ${CPPCHECK_TOOL_PATH} \
         --std=c++17 \
         --enable=all \
         --inconclusive \
-        -j 4 \
-        -i ${PROJECT_BINARY_DIR}/CMakeFiles \
-        -i ${PROJECT_SOURCE_DIR}/ThirdParty \
-        -i ${PROJECT_SOURCE_DIR}/Applications/DataExplorer \
-        -i ${PROJECT_SOURCE_DIR}/Tests \
-        --template='{\n  "description": "{message}",\n  "location": {\n    "path": "{file}",\n    "lines": {\n      "begin": {line}\n    }\n  }\n},' \
+        -j ${CPPCHECK_PARALLEL} \
+        --suppress=*:*/usr/local\* \
+        --suppress=*:*ThirdParty\* \
+        --suppress=*:*Tests\* \
+        --template='{\n  "description": "{message}",\n  "severity": "info",\n    "location": {\n    "path": "{file}",\n    "lines": {\n      "begin": {line}\n    }\n  }\n},' \
         --output-file=$OUTPUT_FILE \
 
 echo "$( \
@@ -26,3 +25,7 @@ echo "$( \
   sed '$s/,$//'; \
   printf ']\n')" \
   > $OUTPUT_FILE
+
+if [ -f ${Python3_EXECUTABLE} ]; then
+    ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/test/cppcheck_gen_hashes.py $OUTPUT_FILE
+fi
diff --git a/scripts/test/cppcheck_gen_hashes.py b/scripts/test/cppcheck_gen_hashes.py
new file mode 100644
index 0000000000000000000000000000000000000000..189fb42955d24c7e71eda27d94f0ebaf49014a88
--- /dev/null
+++ b/scripts/test/cppcheck_gen_hashes.py
@@ -0,0 +1,19 @@
+# Inserts hashes of description + file path as GitLab code quality fingerprint
+import hashlib
+import json
+import sys
+
+data = None
+with open(sys.argv[1]) as json_file:
+    data = json.load(json_file)
+
+for entry in data:
+    desc = entry["description"]
+    path = entry["location"]["path"]
+    hash = hashlib.sha256((desc + path).encode("utf-8")).hexdigest()
+    entry["fingerprint"] = hash
+
+with open(sys.argv[1], "w") as outfile:
+    json.dump(data, outfile)
+
+print("Added cppcheck fingerprints to {}.".format(sys.argv[1]))