-
Notifications
You must be signed in to change notification settings - Fork 20
/
FindCppCheck.cmake
156 lines (130 loc) · 5.17 KB
/
FindCppCheck.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#
# FindCppCheck.cmake
#
# This file is based on following work https://cmake.org/Wiki/PC-Lint
#
# (C) 2015 by Sergei Nikulov
#
# Variables defined:
# CPPCHECK_FOUND - ON/OFF - found/not found
# CPPCHECK_EXECUTABLE - path to cppcheck if found
#
# Function defined:
# add_cppcheck(<target>) target to check with cppcheck
# this function will define build target named <target>_CPPCHECK,
# to run static analysis agains source files from target.
#
set(WHINTS
"$ENV{ProgramFiles}/Cppcheck"
"$ENV{ProgramW6432}/Cppcheck"
)
find_program(CPPCHECK_EXECUTABLE NAMES cppcheck
HINTS ${WHINTS} ENV PATH
PATHS ${WHINTS} ENV PATH
DOC "Path to cppcheck executable")
mark_as_advanced(CPPCHECK_EXECUTABLE)
if(CPPCHECK_EXECUTABLE)
# get version string
execute_process(COMMAND ${CPPCHECK_EXECUTABLE} --version
OUTPUT_VARIABLE _cc_version_output
ERROR_VARIABLE _cc_version_error
RESULT_VARIABLE _cc_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${_cc_version_result} EQUAL 0)
message(SEND_ERROR "command \"${CPPCHECK_EXECUTABLE} --version\" failed - ${_cc_version_error}")
else()
string(REGEX MATCH "[.0-9]+"
CPPCHECK_VERSION "${_cc_version_output}")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CPPCHECK
REQUIRED_VARS CPPCHECK_EXECUTABLE
VERSION_VAR CPPCHECK_VERSION)
mark_as_advanced(CPPCHECK_VERSION)
if(CPPCHECK_FOUND)
message(STATUS "Enabled static analysis with Cppcheck...")
add_custom_target(ALL_CPPCHECK)
#detect platform flag
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_platform_bits "64")
else()
if(WIN32)
set(_platform_bits "32A")
else()
set(_platform_bits "32")
endif()
endif()
set(_cc_platform "native")
if(WIN32)
list(APPEND PROJECT_COMMON_DEFS "_WIN32")
list(APPEND PROJECT_COMMON_DEFS "WIN32")
list(APPEND PROJECT_COMMON_DEFS "_WINDOWS")
set(_cc_platform "win${_platform_bits}")
elseif(UNIX)
set(_cc_platform "unix${_platform_bits}")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND PROJECT_COMMON_DEFS "__x86_64__")
else()
list(APPEND PROJECT_COMMON_DEFS "__i386__")
endif()
endif()
function(add_cppcheck _target_name)
get_target_property(_cc_includes ${_target_name} INCLUDE_DIRECTORIES)
# get_target_property(_cc_includes ${_target_name} CXX_INCLUDE_WHAT_YOU_USE)
# get_target_property(_cc_defines ${_target_name} COMPILE_DEFINITIONS)
get_target_property(_cc_sources ${_target_name} SOURCES)
get_directory_property(_cc_defines COMPILE_DEFINITIONS)
if(PROJECT_COMMON_DEFS)
list(APPEND _cc_defines ${PROJECT_COMMON_DEFS})
endif()
list(SORT _cc_includes)
list(REMOVE_DUPLICATES _cc_includes)
if(CPPCHECK_DEBUG)
message(STATUS "_cc_includes = ${_cc_includes}")
message(STATUS "_cc_defines = ${_cc_defines}")
message(STATUS "_cc_sources = ${_cc_sources}")
endif()
set(_cc_inc_transformed)
foreach(_inc_dir ${_cc_includes})
list(APPEND _cc_inc_transformed "-I\"${_inc_dir}\"")
endforeach()
set(_cc_def_transformed)
foreach(_one_def ${_cc_defines})
list(APPEND _cc_def_transformed -D${_one_def})
endforeach()
if(CPPCHECK_DEBUG)
message(STATUS "_cc_inc_transformed = ${_cc_inc_transformed}")
message(STATUS "_cc_def_transformed = ${_cc_def_transformed}")
message(STATUS "CMAKE_SYSTEM_INCLUDE_PATH = ${CMAKE_SYSTEM_INCLUDE_PATH}")
message(STATUS "CMAKE_INCLUDE_PATH = ${CMAKE_INCLUDE_PATH}")
endif()
set(_all_rpts)
foreach(sourcefile ${_cc_sources})
if(sourcefile MATCHES \\.c$|\\.cxx$|\\.cpp$|\\.cc$)
get_filename_component(_src_abs ${sourcefile} ABSOLUTE)
get_filename_component(_src_name ${sourcefile} NAME)
# message(STATUS "_src_abs = ${_src_abs}")
# message(STATUS "_src_name = ${_src_name}")
set(_rpt_file_name "${_src_name}.rpt")
set(_rpt_path "${CMAKE_CURRENT_SOURCE_DIR}/cppcheck/reports/${_target_name}")
set(_rpt_dst "${_rpt_path}/${_rpt_file_name}")
file(MAKE_DIRECTORY ${_rpt_path})
add_custom_command(OUTPUT ${_rpt_dst}
COMMAND
${CPPCHECK_EXECUTABLE} --enable=all --inconclusive --platform=${_cc_platform} ${_cc_inc_transformed} ${_cc_def_transformed} ${_src_abs} > ${_rpt_dst} 2>&1
VERBATIM
)
list(APPEND _all_rpts ${_rpt_dst})
else()
endif()
endforeach()
add_custom_target(${_target_name}_CPPCHECK DEPENDS ${_all_rpts})
add_dependencies(ALL_CPPCHECK ${_target_name}_CPPCHECK)
endfunction()
else()
message(STATUS "Cppcheck not found... Static analysis is disabled")
function(add_cppcheck _target_name)
#empty macro
endfunction()
endif()