diff --git a/CMakeLists.txt b/CMakeLists.txt index a10703db..1d48276e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ find_package(GLM REQUIRED) find_package(FFmpeg REQUIRED) find_package(SDL2 REQUIRED) +if(CHECK_CLANGTIDY) + find_package(ClangTidy REQUIRED) +endif() + # Include git hash in source include(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) diff --git a/cmake/modules/FindClangTidy.cmake b/cmake/modules/FindClangTidy.cmake new file mode 100644 index 00000000..3002f7aa --- /dev/null +++ b/cmake/modules/FindClangTidy.cmake @@ -0,0 +1,87 @@ +# - Try to find clang-tidy executable and create clang_tidy_check_target function to check targets +# Once done this will define +# +# CLANG_TIDY_FOUND - system has clang-tidy +# CLANG_TIDY_BIN - path of clang-tidy +# CLANG_TIDY_VERSION - version of clang-tidy +# +# clang_tidy_check_target function: +# usage: +# clang_tidy_check_target( +# TARGET # Target to attach clang-tidy to +# [FORMAT_STYLE ] # Format of clang-tidy output +# [FIX ] # Apply the clang-tidy fixes to the sources +# [CHECK_ALL] # run all clang-tidy checks +# ) +# Copyright (c) 2018 OpenRW project +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# + +find_program(CLANG_TIDY_BIN + clang-tidy +) + +if(CLANG_TIDY_BIN) + set(CLANG_TIDY_FOUND 1) +else() + set(CLANG_TIDY_FOUND 0) +endif() + +if(CLANG_TIDY_BIN) + execute_process( + COMMAND "${CLANG_TIDY_BIN}" --version + OUTPUT_VARIABLE _CLANG_TIDY_VERSION_OUTPUT + ) + string(REGEX MATCH "version ([0-9a-zA-Z\.]+)" _CLANG_TIDY_VERSION "${_CLANG_TIDY_VERSION_OUTPUT}") + if(_CLANG_TIDY_VERSION) + set(CLANG_TIDY_VERSION "${CMAKE_MATCH_1}") + else() + set(CLANG_TIDY_VERSION "unknown") + endif() + + execute_process( + COMMAND "${CLANG_TIDY_BIN}" --help + OUTPUT_VARIABLE _CLANG_TIDY_HELP_OUTPUT + ) + string(FIND "${_CLANG_TIDY_HELP_OUTPUT}" "-format-style" _CLANG_TIDY_FORMAT_STYLE_POS) + if(_CLANG_TIDY_FORMAT_STYLE_POS LESS 0) + set(CLANG_TIDY_FORMAT_STYLE_OPTION "-style=") + else() + set(CLANG_TIDY_FORMAT_STYLE_OPTION "-format-style=") + endif() + + include(CMakeParseArguments) + function(clang_tidy_check_target) + cmake_parse_arguments(CTCT + "CHECK_ALL" #options + "TARGET;FORMAT_STYLE;FIX" #one_value_keywords + "" #multi_value_keywords + ${ARGN} + ) + + set(CLANGTIDY_ARGS "${CLANG_TIDY_BIN}") + if(CTCT_CHECK_ALL) + list(APPEND CLANGTIDY_ARGS "-checks=*") + endif() + if(CTCT_FORMAT_STYLE) + list(APPEND CLANGTIDY_ARGS "${CLANG_TIDY_FORMAT_STYLE_OPTION}${CTCT_FORMAT_STYLE}") + endif() + if(CTCT_FIX) + list(APPEND CLANGTIDY_ARGS "-fix") + endif() + + set_target_properties("${CTCT_TARGET}" + PROPERTIES + C_CLANG_TIDY "${CLANGTIDY_ARGS}" + CXX_CLANG_TIDY "${CLANGTIDY_ARGS}" + ) + endfunction() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ClangTidy + REQUIRED_VARS CLANG_TIDY_BIN + VERSION_VAR CLANG_TIDY_VERSION + ) +mark_as_advanced(CLANG_TIDY_BIN) diff --git a/cmake_configure.cmake b/cmake_configure.cmake index b5a27763..43a3144e 100644 --- a/cmake_configure.cmake +++ b/cmake_configure.cmake @@ -147,17 +147,26 @@ endforeach() include(CMakeParseArguments) -if(CHECK_INCLUDES) +if(CHECK_IWYU) find_package(IncludeWhatYouUse REQUIRED) endif() function(openrw_target_apply_options) set(IWYU_MAPPING "${PROJECT_SOURCE_DIR}/openrw_iwyu.imp") cmake_parse_arguments("OPENRW_APPLY" "" "TARGET" "" ${ARGN}) - if(CHECK_INCLUDES) + if(CHECK_IWYU) iwyu_check(TARGET "${OPENRW_APPLY_TARGET}" EXTRA_OPTS "--mapping_file=${IWYU_MAPPING}" ) endif() + + if(CHECK_CLANGTIDY) + clang_tidy_check_target( + TARGET "${OPENRW_APPLY_TARGET}" + FORMAT_STYLE "file" + FIX "${CHECK_CLANGTIDY_FIX}" + CHECK_ALL + ) + endif() endfunction() diff --git a/cmake_options.cmake b/cmake_options.cmake index d702adab..5deaf2a2 100644 --- a/cmake_options.cmake +++ b/cmake_options.cmake @@ -21,7 +21,10 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: Debug Release") endif() -option(CHECK_INCLUDES "Analyze #includes in C and C++ source files") +option(CHECK_IWYU "Enable IncludeWhatYouUse (Analyze #includes in C and C++ source files)") + +option(CHECK_CLANGTIDY "Enable clang-tidy (A clang-based C++ linter tool)") +option(CHECK_CLANGTIDY_FIX "Apply fixes from clang-tidy (!!!RUN ON CLEAN GIT TREE!!!)") option(TEST_COVERAGE "Enable coverage analysis (implies CMAKE_BUILD_TYPE=Debug)") option(SEPARATE_TEST_SUITES "Add each test suite as separate test to CTest")