1# 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.") 10else() 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.") 22endif() 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") 33list(APPEND cppcheck-flags "--check-level=exhaustive") 34 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}") 46 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() 102 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() 114