Skip to content

Commit

Permalink
Pass include paths to cppcheck (#117)
Browse files Browse the repository at this point in the history
* Use BUILDSYSTEM_TARGETS list for getting include directories

* Only pass include directories that are subdirectories of the package being tested

This eliminates the need for a longer test timeout and avoids cppcheck from testing external files.
Reverted prior changes accordingly.

* Handle case when cppcheck reports error in filename with arbitrary path

* Add find_package and dependency tag for ament_cmake_core
  • Loading branch information
jacobperron authored Jan 10, 2019
1 parent 659bf4d commit 8d2ef3b
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
29 changes: 28 additions & 1 deletion ament_cmake_cppcheck/cmake/ament_cmake_cppcheck_lint_hook.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

find_package(ament_cmake_core REQUIRED)

file(GLOB_RECURSE _source_files FOLLOW_SYMLINKS
"*.c"
"*.cc"
Expand All @@ -24,5 +26,30 @@ file(GLOB_RECURSE _source_files FOLLOW_SYMLINKS
)
if(_source_files)
message(STATUS "Added test 'cppcheck' to perform static code analysis on C / C++ code")
ament_cppcheck()

# Get include paths for added targets
set(_all_include_dirs "")
# BUILDSYSTEM_TARGETS only supported in CMake >= 3.7
if(NOT CMAKE_VERSION VERSION_LESS "3.7.0")
get_directory_property(_build_targets DIRECTORY ${CMAKE_SOURCE_DIR} BUILDSYSTEM_TARGETS)
foreach(_target ${_build_targets})
get_property(_include_dirs
TARGET ${_target}
PROPERTY INCLUDE_DIRECTORIES
)

# Only append include directories that are from the package being tested
# This accomplishes two things:
# 1. Reduces execution time (less include directories to search)
# 2. cppcheck will not check for errors in external packages
foreach(_include_dir ${_include_dirs})
string(REGEX MATCH "^${CMAKE_SOURCE_DIR}.*" _is_match ${_include_dir})
if(_is_match)
list_append_unique(_all_include_dirs ${_include_dir})
endif()
endforeach()
endforeach()
endif()

ament_cppcheck(INCLUDE_DIRS ${_all_include_dirs})
endif()
7 changes: 6 additions & 1 deletion ament_cmake_cppcheck/cmake/ament_cppcheck.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
# :type TESTNAME: string
# :param LANGUAGE: the language argument for cppcheck, either 'c' or 'c++'
# :type LANGUAGE: string
# :param INCLUDE_DIRS: an optional list of include paths for cppcheck
# :type INCLUDE_DIRS: list
# :param ARGN: the files or directories to check
# :type ARGN: list of strings
#
# @public
#
function(ament_cppcheck)
cmake_parse_arguments(ARG "" "LANGUAGE;TESTNAME" "" ${ARGN})
cmake_parse_arguments(ARG "" "LANGUAGE;TESTNAME" "INCLUDE_DIRS" ${ARGN})
if(NOT ARG_TESTNAME)
set(ARG_TESTNAME "cppcheck")
endif()
Expand All @@ -38,6 +40,9 @@ function(ament_cppcheck)
set(result_file "${AMENT_TEST_RESULTS_DIR}/${PROJECT_NAME}/${ARG_TESTNAME}.xunit.xml")
set(cmd "${ament_cppcheck_BIN}" "--xunit-file" "${result_file}")
list(APPEND cmd ${ARG_UNPARSED_ARGUMENTS})
if(ARG_INCLUDE_DIRS)
list(APPEND cmd "--include_dirs" "${ARG_INCLUDE_DIRS}")
endif()
if(ARG_LANGUAGE)
list(APPEND cmd "--language" "${ARG_LANGUAGE}")
endif()
Expand Down
1 change: 1 addition & 0 deletions ament_cmake_cppcheck/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<buildtool_depend>ament_cmake_core</buildtool_depend>
<buildtool_depend>ament_cmake_test</buildtool_depend>

<buildtool_export_depend>ament_cmake_core</buildtool_export_depend>
<buildtool_export_depend>ament_cmake_test</buildtool_export_depend>
<buildtool_export_depend>ament_cppcheck</buildtool_export_depend>

Expand Down
12 changes: 9 additions & 3 deletions ament_cppcheck/ament_cppcheck/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# limitations under the License.

import argparse
from collections import defaultdict
import multiprocessing
import os
from shutil import which
Expand All @@ -39,6 +40,11 @@ def main(argv=sys.argv[1:]):
help='Files and/or directories to be checked. Directories are searched recursively for '
'files ending in one of %s.' %
', '.join(["'.%s'" % e for e in extensions]))
parser.add_argument(
'--include_dirs',
nargs='*',
help="Include directories for C/C++ files being checked."
"Each directory is passed to cppcheck as '-I <include_dir>'")
parser.add_argument(
'--language',
help="Passed to cppcheck as '--language=<language>', and it forces cppcheck to consider "
Expand Down Expand Up @@ -86,6 +92,8 @@ def main(argv=sys.argv[1:]):
'--xml-version=2']
if args.language:
cmd.extend(['--language={0}'.format(args.language)])
for include_dir in (args.include_dirs or []):
cmd.extend(['-I', include_dir])
if jobs:
cmd.extend(['-j', '%d' % jobs])
cmd.extend(files)
Expand All @@ -105,9 +113,7 @@ def main(argv=sys.argv[1:]):
return 1

# output errors
report = {}
for filename in files:
report[filename] = []
report = defaultdict(list)
for error in root.find('errors'):
location = error.find('location')
filename = location.get('file')
Expand Down

0 comments on commit 8d2ef3b

Please sign in to comment.