add static analysis support to buildsystem

This commit is contained in:
Arne Morten Kvarving
2017-06-01 15:45:11 +02:00
parent 6d2194edc2
commit cdbcb74e5e
8 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
# Find clang-check.
#
# This module defines:
# CLANGCHECK_PROGRAM, the clang-check executable.
# CLANGHCECK_FOUND, If false, do not try to use cppcheck.
#
find_program(CLANGCHECK_PROGRAM NAMES clang-check clang-check-3.8)
find_package_handle_standard_args(ClangCheck DEFAULT_MSG CLANGCHECK_PROGRAM)
mark_as_advanced(CLANGCHECK_PROGRAM)

View File

@@ -0,0 +1,11 @@
# Find CppCheck.
#
# This module defines:
# CPPCHECK_PROGRAM, the cppcheck executable.
# CPPCHECK_FOUND, If false, do not try to use cppcheck.
#
find_program(CPPCHECK_PROGRAM NAMES cppcheck)
find_package_handle_standard_args(CppCheck DEFAULT_MSG CPPCHECK_PROGRAM)
mark_as_advanced(CPPCHECK_PROGRAM)

View File

@@ -57,6 +57,7 @@ macro (opm_compile opm)
# queue this executable to be stripped
strip_debug_symbols (${${opm}_TARGET} ${opm}_DEBUG)
endif()
add_static_analysis_tests(${opm}_SOURCES ${opm}_INCLUDE_DIRS)
else (${opm}_SOURCES)
# unset this variable to signal that no library is generated
set (${opm}_TARGET)

View File

@@ -102,6 +102,10 @@ find_openmp (${project})
include (UseThreads)
find_threads (${project})
# static code analysis
include(UseStaticAnalysis)
setup_static_analysis_tools()
# callback hook to setup additional dependencies
if (COMMAND prereqs_hook)
prereqs_hook ()

View File

@@ -72,6 +72,7 @@ macro (opm_compile_satellites opm satellite excl_all test_regexp)
set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
else (NOT "${test_regexp}" STREQUAL "")
set (_test_lib "")
add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS)
endif (NOT "${test_regexp}" STREQUAL "")
target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib})
if (STRIP_DEBUGGING_SYMBOLS)

View File

@@ -0,0 +1,50 @@
# Add static analysis tests for a given source file
macro(setup_static_analysis_tools)
find_package(CppCheck)
if(CMAKE_EXPORT_COMPILE_COMMANDS)
find_package(ClangCheck)
else()
message(STATUS "Disabling clang-check as CMAKE_EXPORT_COMPILE_COMMANDS is not enabled")
endif()
if(OPM_COMMON_ROOT)
set(DIR ${OPM_COMMON_ROOT})
elseif(OPM_MACROS_ROOT)
set(DIR ${OPM_MACROS_ROOT})
else()
set(DIR ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(CPPCHECK_FOUND)
file(COPY ${DIR}/cmake/Scripts/cppcheck-test.sh
DESTINATION bin
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif()
if(CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS)
configure_file(${DIR}/cmake/Scripts/clang-check-test.sh.in
${CMAKE_BINARY_DIR}/CMakeFiles/clang-check-test.sh)
file(COPY ${CMAKE_BINARY_DIR}/CMakeFiles/clang-check-test.sh
DESTINATION bin
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif()
endmacro()
function(add_static_analysis_tests sources includes)
if(CPPCHECK_FOUND OR (CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS))
foreach(dep ${${includes}})
list(APPEND IPATHS -I ${dep})
endforeach()
foreach(src ${${sources}})
file(RELATIVE_PATH name ${PROJECT_SOURCE_DIR} ${src})
if(CPPCHECK_FOUND)
add_test(NAME cppcheck+${name}
COMMAND bin/cppcheck-test.sh ${CPPCHECK_PROGRAM} ${src} ${IPATHS}
CONFIGURATIONS analyze cppcheck)
endif()
if(CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS)
add_test(NAME clang-check+${name}
COMMAND bin/clang-check-test.sh ${CLANGCHECK_PROGRAM} ${src}
CONFIGURATIONS analyze clang-check)
endif()
endforeach()
endif()
endfunction()

View File

@@ -0,0 +1,23 @@
#!/bin/bash
# This script performs a single analysis using clang-check
# It is used by the 'make test' target in the buildsystems
# Usually you should use 'ctest -C clang-check' rather than calling this script directly
#
# Parameters: $1 = Application binary
# $2 = Source file to process
clangcheck_cmd=$1
source_file=$2
tmpfil=`mktemp`
$clangcheck_cmd -p @CMAKE_BINARY_DIR@ -analyze $source_file &> $tmpfil
cat $tmpfil
if test -s $tmpfil
then
rm $tmpfil
exit 1
fi
rm $tmpfil
exit 0

30
cmake/Scripts/cppcheck-test.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
# This script performs a single analysis using cppcheck
# It is used by the 'make test' target in the buildsystems
# Usually you should use 'ctest -C cppcheck' rather than calling this script directly
#
# Parameters: $1 = Application binary
# $2 = Source file to process
# $3..$N = include path parameters (-I dir1 -I dir2 ...)
cppcheck_cmd=$1
source_file=$2
shift 2
tmpfil=`mktemp`
$cppcheck_cmd $@ --enable=all --suppress=unusedFunction $source_file &> $tmpfil
nmatch=`cat $tmpfil | grep "\[.*\]" | wc -l`
nsys=`cat $tmpfil | grep "\[/usr.*\]" | wc -l`
nnone=`cat $tmpfil | grep "\[\\*]" | wc -l`
ndef=`cat $tmpfil | grep "\[.*Too many #ifdef" | wc -l`
let "nval=$nmatch-$nsys-$nnone-$ndef"
if test $nval -gt 0
then
cat $tmpfil
rm $tmpfil
exit 1
fi
rm $tmpfil
exit 0