diff --git a/CMakeLists.txt b/CMakeLists.txt index e356d28..e65d5b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,6 +257,10 @@ if (GTK_DOC_FOUND) HTML ${project_DOC_DIR}/html) endif (GTK_DOC_FOUND) +find_package (CppCheck) +GENERATE_CPPCHECK (SOURCES liblogdiag src tests ENABLE_IDS all + TARGET_NAME ${CMAKE_PROJECT_NAME}_cppcheck INCLUDES ${CMAKE_CURRENT_BINARY_DIR}) + # GSettings find_program (GLIB_COMPILE_SCHEMAS_EXECUTABLE glib-compile-schemas) if (NOT GLIB_COMPILE_SCHEMAS_EXECUTABLE) diff --git a/cmake/FindCppCheck.cmake b/cmake/FindCppCheck.cmake new file mode 100644 index 0000000..a379ace --- /dev/null +++ b/cmake/FindCppCheck.cmake @@ -0,0 +1,156 @@ +# - Find cppcheck +# This module looks for cppcheck. +# This module defines the following variables: +# +# CPPCHECK_FOUND - Set to TRUE when cppcheck is found. +# CPPCHECK_EXECUTABLE - Path to the executable. +# +# and a convenience function for calling the utility: +# +# GENERATE_CPPCHECK(SOURCES +# [SUPPRESSION_FILE ] +# [ENABLE_IDS ] +# [TARGET_NAME ] +# [INCLUDES ]) +# +# This generates a "cppcheck" target that executes cppcheck on the specified +# sources. Sources may be either file names or directories containing files +# where all C/++ files will be parsed automatically. Use directories whenever +# possible because there is a limitation in arguments to pass to the cppcheck +# binary. +# +# SUPPRESSION_FILE may be given additionally to specify suppressions for +# cppcheck. The sources mentioned in the suppression file must be in the same +# format as given for SOURCES. This means if you specify them relative to +# CMAKE_CURRENT_SOURCE_DIR, then the same relative paths must be used in the +# suppression file. +# +# ENABLE_IDS allows to specify which additional cppcheck check ids to execute, +# e.g. all or style. +# +# With TARGET_NAME a different name for the generated check target can be +# specified. This is useful if several calls to this function are made in one +# CMake project, as otherwise the target names would collide. +# +# Additional include directories for the cppcheck program can be given with +# INCLUDES. +# +# cppcheck will be executed with CMAKE_CURRENT_SOURCE_DIR as working directory. +# +# This function can be called even if cppcheck wasn't found. In that case no +# target is created. +# +# + +#============================================================================= +# Copyright 2011 Johannes Wienke +# Copyright 2012 Přemysl Janouch +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +#============================================================================= + + +find_program (CPPCHECK_EXECUTABLE cppcheck) +mark_as_advanced (CPPCHECK_EXECUTABLE) + +include (FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS (CppCheck DEFAULT_MSG CPPCHECK_EXECUTABLE) + +include (ProcessArguments) + +function (GENERATE_CPPCHECK) + if (NOT CPPCHECK_FOUND) + return () + endif (NOT CPPCHECK_FOUND) + + # Parse arguments given to this function + set (__names SOURCES SUPPRESION_FILE ENABLE_IDS TARGET_NAME INCLUDES) + set (__need YES NO NO NO NO) + set (__want 1 1 1 1 1) + set (__more YES NO YES NO YES) + set (__skip 0 0 0 0 0) + + set (__argv ${ARGV}) + PROCESS_ARGUMENTS (__argv __names __need __want __more __skip "opt_") + + # Get target name + set (target_name "cppcheck") + set (target_name_suffix "") + + if (opt_target_name) + set (target_name ${opt_target_name_param}) + set (target_suffix "-${target_name}") + endif (opt_target_name) + + set (cppcheck_base "${PROJECT_BINARY_DIR}/cppcheck${target_suffix}") + + set (cppcheck_report_file "${cppcheck_base}-report.log") + set (cppcheck_wrapper_script "${cppcheck_base}.cmake") + + # Prepare a command line for cppcheck + set (source_args ${opt_sources_param}) + set (options "--inline-suppr") + + # Suppression argument + if (opt_suppression_file) + get_filename_component (abs "${opt_suppression_file_param}" ABSOLUTE) + set (options "${options} --suppressions \"${abs}\"") + endif (opt_suppression_file) + + # Includes + foreach (include ${opt_includes_param}) + set (options "${options} -I \"${include}\"") + endforeach (include) + + # Enabled ids + if (opt_enable_ids) + set (id_list "") + foreach (id ${opt_enable_ids_param}) + set (id_list "${id_list},${id}") + endforeach (id) + + string (SUBSTRING ${id_list} 1 -1 id_list) + set (options "${options} \"--enable=${id_list}\"") + endif (opt_enable_ids) + + # Create a wrapper script which redirects stderr of cppcheck to a file + file (WRITE ${cppcheck_wrapper_script} " + execute_process ( + COMMAND \"${CPPCHECK_EXECUTABLE}\" ${options} ${source_args} + RESULT_VARIABLE exit_code + ERROR_VARIABLE error_out + WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\") + if (exit_code) + message (FATAL_ERROR \"Error executing cppcheck\") + endif (exit_code) + if (error_out) + message (\"\\nDetected errors:\\n\${error_out}\") + endif (error_out) + file (WRITE \"${cppcheck_report_file}\" \"\${error_out}\") + ") + + add_custom_target (${target_name} + COMMAND ${CMAKE_COMMAND} -P "${cppcheck_wrapper_script}" + DEPENDS "${cppcheck_wrapper_script}" + COMMENT "Calling cppcheck static code analyzer" VERBATIM) +endfunction (GENERATE_CPPCHECK) +