diff --git a/.travis.yml b/.travis.yml index e73ecca1..bbc1ab4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,10 +49,12 @@ matrix: - os: linux compiler: clang env: SCAN_BUILD=YES + before_install: + - sudo apt-get install -y cppcheck before_script: - - if [ "$(uname)" = "Linux" ]; then sudo apt-get update; sudo apt-get install -y texlive texinfo texi2html doxygen; fi - - if [ "$(uname)" = "Darwin" ]; then brew update; brew cask install mactex; brew install texi2html texinfo doxygen; fi + - if [ "$(uname)" = "Linux" ]; then sudo apt-get update; sudo apt-get install -y texlive texinfo texi2html doxygen cppcheck; fi + - if [ "$(uname)" = "Darwin" ]; then brew update; brew cask install mactex; brew install texi2html texinfo doxygen cppcheck; fi script: - chmod +x travis.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index d4d16aaa..a5b1c2ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,9 @@ if(POLICY CMP0076) # target_sources() leaves relative source file paths unmodified. (OLD) cmake_policy(SET CMP0076 OLD) endif() +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) # Use _ROOT variables +endif() project(Check DESCRIPTION "Unit Testing Framework for C" LANGUAGES C) @@ -75,6 +78,9 @@ if(NOT CHECK_ENABLE_TESTS) # TODO Remove this option by Check 0.15.0! endif(NOT CHECK_ENABLE_TESTS) +option(ENABLE_TREAT_WARNINGS_AS_ERRORS + "Fail build if compiler, linker, static analysis tools or other QA tool finds faults" OFF) + option(CHECK_ENABLE_GCOV "Turn on test coverage" OFF) if (CHECK_ENABLE_GCOV AND NOT ${CMAKE_C_COMPILER_ID} MATCHES "GNU") @@ -444,6 +450,43 @@ install( DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) +############################################################################### +# CMake enabled static analysis + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + # Different tests are only executed when the corresponding + # tools are available. Presence in the system is checked individually. + # + # Run analysis only when the build type is Debug, + # not any of the Release variants. + # In the future Cppcheck and other tools will improve + # and find new faults in our code. + # We do not want to create headache for the future admins and packagers, + # only for the future programmers. + + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.10") + # CMAKE__CPPCHECK only supported in 3.10 and upwards. + # E.g. CMAKE__CPPLINT already since CMake 3.8. + find_package(Cppcheck) + if(Cppcheck_FOUND) + set(cppcheck_c_standard "c${CMAKE_C_STANDARD}") + if("${cppcheck_c_standard}" STREQUAL "c90") + set(cppcheck_c_standard "c89") + endif() + set(cppcheck_error_exitcode "0") + if(ENABLE_TREAT_WARNINGS_AS_ERRORS) + set(cppcheck_error_exitcode "1") + endif() + list(APPEND CMAKE_C_CPPCHECK "${Cppcheck_EXECUTABLE}") + list(APPEND CMAKE_C_CPPCHECK "--quiet") + list(APPEND CMAKE_C_CPPCHECK "--error-exitcode=${cppcheck_error_exitcode}") + list(APPEND CMAKE_C_CPPCHECK "--std=${cppcheck_c_standard}") + list(APPEND CMAKE_C_CPPCHECK "--enable=warning,style,performance,portability") + endif(Cppcheck_FOUND) + endif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.10") + +endif(CMAKE_BUILD_TYPE STREQUAL "Debug") + ############################################################################### # Subdirectories add_subdirectory(lib) diff --git a/cmake/FindCppcheck.cmake b/cmake/FindCppcheck.cmake new file mode 100644 index 00000000..95d27a03 --- /dev/null +++ b/cmake/FindCppcheck.cmake @@ -0,0 +1,31 @@ +find_program( + Cppcheck_EXECUTABLE + NAMES cppcheck + DOC "Cppcheck static analysis tool (http://cppcheck.sourceforge.net)" +) + +if (Cppcheck_EXECUTABLE) + execute_process( + COMMAND ${Cppcheck_EXECUTABLE} --version + OUTPUT_VARIABLE cppcheck_version_out + RESULT_VARIABLE cppcheck_version_error + ERROR_VARIABLE cppcheck_version_suppress + ) + if (NOT cppcheck_version_error) + string(REPLACE "\n" "" cppcheck_version_out "${cppcheck_version_out}") + string(REGEX REPLACE "Cppcheck (.+)" "\\1" cppcheck_version "${cppcheck_version_out}") + endif () +endif () + +if (cppcheck_version) + set(Cppcheck_FOUND 1 CACHE INTERNAL "Cppcheck version ${cppcheck_version} found") + set(Cppcheck_VERSION "${cppcheck_version}" CACHE INTERNAL "Cppcheck version number") +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Cppcheck + REQUIRED_VARS Cppcheck_EXECUTABLE + VERSION_VAR Cppcheck_VERSION +) + diff --git a/travis.sh b/travis.sh index f455a31c..4c993b70 100644 --- a/travis.sh +++ b/travis.sh @@ -31,7 +31,7 @@ fi if [ "${USE_CMAKE}" = 'YES' ] ; then cmake --version - cmake . || exit 1 + cmake . -DENABLE_TREAT_WARNINGS_AS_ERRORS=ON || exit 1 make || exit 1 ctest -V || exit 1 sudo make install || exit 1 @@ -84,7 +84,7 @@ if [ "${PRE_RELEASE_CHECK}" = 'YES' ]; then tar xf check-*.tar.gz cd check-* cmake --version - cmake . || exit 1 + cmake . -DENABLE_TREAT_WARNINGS_AS_ERRORS=ON || exit 1 make || exit 1 fi