blob: 12d1700a8aca687d369d0bb09971a3c3d7f2ff6d [file] [log] [blame]
Soby Mathew7faa95e2023-11-22 17:04:10 +00001#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6find_program(RMM_CPPCHECK_EXE "cppcheck" DOC "Path to Cppcheck")
7
8if(NOT RMM_CPPCHECK_EXE)
9 message(FATAL_ERROR "Could not find cppcheck executable.")
Sona Mathew44713562024-08-11 23:18:32 -050010else()
11 message(cppcheck_path: "${RMM_CPPCHECK_EXE}")
12 execute_process(COMMAND ${RMM_CPPCHECK_EXE} --version
13 OUTPUT_VARIABLE CPPCHECK_INSTALLED_VERSION)
14 string(REGEX MATCH "([0-9]+\\.[0-9]+(\\.[0-9]+)?)" CPPCHECK_INSTALLED ${CPPCHECK_INSTALLED_VERSION})
15 message(Installed version: "${CPPCHECK_INSTALLED}")
16 set(CPPCHECK_MIN_REQD "2.14.0")
17endif()
18
19if("${CPPCHECK_INSTALLED}" VERSION_LESS "${CPPCHECK_MIN_REQD}")
20 message(WARNING "Cppcheck installed version is: ${CPPCHECK_INSTALLED}, minimum required version is ${CPPCHECK_MIN_REQD}.")
21 message(WARNING "Cppcheck output will not be checked for errors.")
Soby Mathew7faa95e2023-11-22 17:04:10 +000022endif()
23
24#
25# Set up checkers.
26#
27set(cppcheck-flags)
28
29list(APPEND cppcheck-flags "--enable=all")
30list(APPEND cppcheck-flags "--xml")
31list(APPEND cppcheck-flags "--xml-version=2")
32list(APPEND cppcheck-flags "--template=gcc")
Shruti Guptae825dfc2024-04-15 11:09:25 +010033list(APPEND cppcheck-flags "--check-level=exhaustive")
Soby Mathew7faa95e2023-11-22 17:04:10 +000034
35if(CPPCHECK_MISRA)
36 list(APPEND cppcheck-flags "--addon=${SOURCE_DIR}/tools/cppcheck/misra.json")
37 set(CPPCHECK_OUTPUT "${BUILD_DIR}/tools/cppcheck/cppcheck_misra.xml")
38 set(CPPCHECK_BUILD_DIR "${BUILD_DIR}/tools/cppcheck/dump_misra")
39else()
40 set(CPPCHECK_OUTPUT "${BUILD_DIR}/tools/cppcheck/cppcheck.xml")
41 set(CPPCHECK_BUILD_DIR "${BUILD_DIR}/tools/cppcheck/dump")
42endif()
43
44list(APPEND cppcheck-flags "--output-file=${CPPCHECK_OUTPUT}")
45list(APPEND cppcheck-flags "--cppcheck-build-dir=${CPPCHECK_BUILD_DIR}")
Soby Mathew7faa95e2023-11-22 17:04:10 +000046
47#
48# Exclude files or directories we don't want to receive warnings about.
49#
50list(APPEND cppcheck-flags "-i${SOURCE_DIR}/ext/")
51list(APPEND cppcheck-flags "-i${SOURCE_DIR}/lib/libc")
52
53#
54# If you want to suppress specific files without using an inline suppression,
55# do it in `suppressions.txt`.
56#
57list(APPEND cppcheck-flags
58 "--inline-suppr" # Allow inline suppressions
59 "--suppressions-list=${SOURCE_DIR}/tools/cppcheck/suppressions.txt")
60
61#
62# Configure the platform file. This communicates certain implementation details to
63# Cppcheck and avoid false positives.
64#
65set(toolchain-xml
66 "${SOURCE_DIR}/tools/cppcheck-aarch64-platform.xml")
67
68list(APPEND cppcheck-flags "--platform=${toolchain-xml}")
69set(COMPILE_COMMANDS_FILE "${BUILD_DIR}/compile_commands.json")
70if(NOT EXISTS "${COMPILE_COMMANDS_FILE}")
71 message(FATAL_ERROR "Please configure with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON.")
72endif()
73
74#
75# Create the output directory
76#
77file(MAKE_DIRECTORY "${CPPCHECK_BUILD_DIR}")
78
79set(EXE_CPPCHECK_TWICE)
80
81#
82# Workaround for "internal errors" reported for cppcheck-misra.
83# Run CPPCheck 2nd time if the output file is not created.
84#
85if(CPPCHECK_MISRA AND (NOT EXISTS "${CPPCHECK_OUTPUT}"))
86 set(EXE_CPPCHECK_TWICE 1)
87endif()
88
89execute_process(
90 WORKING_DIRECTORY ${SOURCE_DIR}
91 COMMAND ${RMM_CPPCHECK_EXE}
92 --project=${COMPILE_COMMANDS_FILE} ${cppcheck-flags}
93 )
94
95if(EXE_CPPCHECK_TWICE)
96 execute_process(
97 WORKING_DIRECTORY ${SOURCE_DIR}
98 COMMAND ${RMM_CPPCHECK_EXE}
99 --project=${COMPILE_COMMANDS_FILE} ${cppcheck-flags}
100 )
101endif()
Sona Mathew44713562024-08-11 23:18:32 -0500102
103if((EXISTS "${CPPCHECK_OUTPUT}") AND ("${CPPCHECK_INSTALLED}" VERSION_GREATER_EQUAL "${CPPCHECK_MIN_REQD}"))
104 file(READ "${CPPCHECK_OUTPUT}" cppcheck_xml)
105 string(REGEX MATCHALL "<error id" errtag "${cppcheck_xml}")
106 list(LENGTH errtag errcount)
107
108 if (${errcount} EQUAL 0)
109 message("Good work! No Cppcheck errors detected")
110 else()
111 message(FATAL_ERROR "Cppcheck failed with error count: ${errcount}")
112 endif()
113endif()