cmakeを使って、clang-tidyやclang-formatを行う


C/C++でコードを書く場合、clang-tidyclang-formatはとても便利です。
CMakeで、任意のターゲット1に対して、clang-tidyclang-formatを行えるようにしました。

FormatFilesWithClangFormat.cmake
option(FORMAT_FILES_WITH_CLANG_FORMAT_BEFORE_EACH_BUILD
  "If the command clang-format is avilable, format source files before each build.\
Turn this off if the build time is too slow."
  ON)
find_program(CLANG_FORMAT_EXE clang-format)

function(clang_format target)
  if(CLANG_FORMAT_EXE)
    message(STATUS "Enable Clang-Format ${target}")
    get_target_property(MY_SOURCES ${target} SOURCES)
    add_custom_target(
      "${target}_format-with-clang-format"
      COMMAND "${CLANG_FORMAT_EXE}" -i -style=file ${MY_SOURCES}
      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
      )
    if(FORMAT_FILES_WITH_CLANG_FORMAT_BEFORE_EACH_BUILD)
      add_dependencies(${target} "${target}_format-with-clang-format")
    endif()
  endif()
endfunction()
DoClangTidy.cmake
cmake_minimum_required(VERSION 3.6)
option(CLANG_TIDY_ENABLE
  "If the command clang-tidy is avilable, tidy source files.\
Turn this off if the build time is too slow."
  ON)
find_program(CLANG_TIDY_EXE clang-tidy)

function(clang_tidy target)
  if(CLANG_TIDY_EXE)
    if(CLANG_TIDY_ENABLE)
      message(STATUS "Enable Clang-Tidy ${target}")
      set_target_properties(${target} PROPERTIES
        C_CLANG_TIDY "${CLANG_TIDY_EXE};-fix;-fix-errors"
        CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-fix;-fix-errors")
      endif()
  endif()
endfunction()
使い方
include(DoClangTidy)
include(FormatFilesWithClangFormat)

set(target nice_app)
add_executable(${target}
  main.cpp
)
clang_format(${target})
clang_tidy(${target})

解説

FormatFilesWithClangFormat.cmake/DoClangTidy.cmakeincludeします。
すると、関数clang_tidy(target)/clang_format(target)が定義されます。これを呼ぶとターゲットのビルド時にclang-tidy/clang-formatが行われるようになります。
また、有効/無効化やコマンドパスを設定するオプションも設定されます。ccmake等で編集できます。

チェック内容やインデント設定等は、上記cmakeファイルを(コマンド引数に足す)のではなく、.clang-tidy/.clang-formatファイルで設定するのがおすすめです。

参考


  1. グローバルに設定したら、ExternalProject(googletest)でえらいことになってしまった