INCLUDE(CheckParent)
find_program(CPPCHECK NAMES cppcheck)

#
# check if the GENERATE_CPPCHECK function has already been defined
#
get_property(_GENERATE_CPPCHECK GLOBAL PROPERTY _GENERATE_CPPCHECK)
IF (NOT _GENERATE_CPPCHECK)

  # set that we have defined GENERATE_CCCC
  set_property(GLOBAL PROPERTY _GENERATE_CPPCHECK "YES")

  FUNCTION(GENERATE_CPPCHECK)
    IF(NOT TARGET cppcheck)
  	IF(CPPCHECK)
      CMAKE_PARSE_ARGUMENTS(ARG  "" "" "TARGETS" ${ARGN})
      get_property(_cppcheckfiles GLOBAL PROPERTY _cppcheckfiles)
      get_property(_cppcheckincludedirs GLOBAL PROPERTY _cppcheckincludedirs)

      foreach(_target ${ARG_TARGETS})
        get_target_property(_sources ${_target} SOURCES)
        get_target_property(_source_dir ${_target} SOURCE_DIR)
        get_target_property(_include_dir ${_target} INCLUDE_DIRECTORIES)
        string(REPLACE "$<" ";" _include_dirs ${_include_dir})

        foreach(_dir ${_include_dirs})
          list(APPEND _cppcheckincludedirs -I${_include_dir})
        endforeach()

        foreach(_source ${_sources})
          set(_fullsource "${_source_dir}/${_source}")
          list(APPEND _cppcheckfiles ${_fullsource})
        endforeach()
  		endforeach()
      set_property(GLOBAL PROPERTY _cppcheckfiles ${_cppcheckfiles})
      set_property(GLOBAL PROPERTY _cppcheckincludedirs ${_cppcheckincludedirs})
    ENDIF()
  ENDIF()
  ENDFUNCTION()

  FUNCTION(RESET_CPPCHECK)
    set_property(GLOBAL PROPERTY _cppcheckfiles "")
    set_property(GLOBAL PROPERTY _cppcheckincludedirs "")
  ENDFUNCTION()


  FUNCTION(GENERATE_CPPCHECK_TARGET)
    IF ( NOT hasParent AND CPPCHECK)
        message("generate cppcheck target")
        get_property(_targetcppcheckfiles GLOBAL PROPERTY _cppcheckfiles)
        get_property(_targetcppcheckincludedirs GLOBAL PROPERTY _cppcheckincludedirs)

        add_custom_target(cppcheck
          COMMAND
          ${CPPCHECK}
          --xml
          --xml-version=2
          --enable=all
          --inconclusive
          --force
          --inline-suppr
          ${_targetcppcheckincludedirs}
          ${_targetcppcheckfiles}
          2> cppcheck.xml
          WORKING_DIRECTORY
          ${CMAKE_CURRENT_BINARY_DIR}
          COMMENT
          "cppcheck: Running cppcheck on target ${_targetname}..."
          VERBATIM)

    ENDIF()
  ENDFUNCTION()

ENDIF()
