プロジェクトをリントするために、clang-tidy用のカスタムcmakeターゲットを作成しようとしています。ソースフォルダは次のようになります。
src/scripts/run-clang-tidy.py
src/.clang-tidy
src/...
これまでの私の計画は、カスタムコマンドを使用してこれら両方のファイルをビルドディレクトリにコピーすることでした。
add_custom_command(
OUTPUT run-clang-tidy.py .clang-tidy
COMMAND cp ${CMAKE_SOURCE_DIR}/scripts/run-clang-tidy.py ${CMAKE_SOURCE_DIR}/.clang-tidy ${CMAKE_CURRENT_BINARY_DIR})
ここで、ビルドディレクトリ(作業ディレクトリである必要があります)のrun-clang-tidy.py
をカスタムターゲットで呼び出して、次のように呼び出すことができます。
make lint
.clang-tidy
で指定されたチェックを実行する必要があります。
このスクリプトを機能させるには、CMAKE_EXPORT_COMPILE_COMMANDS
オプションも必要です。次のコマンドで設定しようとしましたが、認識されません。
add_definitions(-DCMAKE_EXPORT_COMPILE_COMMANDS=ON)
add_custom_target
の呼び出しはどのようになりますか?
追加のPythonスクリプトを必要としない別の方法を提案できます。
まず、clang-tidy
とclang-format
をカスタムCMakeルールに統合したかったので、最初にプロジェクトのルートディレクトリにある.clang-tidy
ファイルと.clang-format
ファイルを生成しました。
.clang-tidy
を生成するには、最初にプロジェクトに適したオプションを見つけてから、次の手順を実行します。
$> clang-tidy <source-files> -dump-config <tidy-options> -- <compile-options> > .clang-tidy
同様に、clang-format
の場合、-style=xxx
オプションを使用してデフォルトのスタイルから開始し、それをダンプすることができます。たとえば、LLVMスタイルから始めます。
$> clang-format -style=LLVM -dump-config > .clang-format
次に、それを編集し、必要に応じて適切に構成します。次のようになります。
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: true
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
BinPackArguments: true
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
...
CMakeを使用すると、非常に簡単な方法でカスタムルールを定義できます。add_custom_target()
プロシージャを呼び出してファイルにCMakeコマンドのセットを記述し、それをCMakeList.txt
ファイルに含めるだけです。これが私たちが行うことです。最初にプロジェクトのルートにcmake/clang-dev-tools.cmake
ファイルを作成します。
# Additional target to perform clang-format/clang-tidy run
# Requires clang-format and clang-tidy
# Get all project files
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.hpp)
add_custom_target(
clang-format
COMMAND /usr/bin/clang-format
-style=file
-i
${ALL_SOURCE_FILES}
)
add_custom_target(
clang-tidy
COMMAND /usr/bin/clang-tidy
${ALL_SOURCE_FILES}
-config=''
--
-std=c++11
${INCLUDE_DIRECTORIES}
)
次に、CMakeLists.txt
を編集して、以下を追加します。
# Including extra cmake rules
include(cmake/clang-dev-tools.cmake)
次に、ビルドシステムが再生成されると、make clang-tidy
とmake clang-format
を実行できるようになります。
Alexander Shukaev で言及されているドキュメントは詳細が少し短いので、例を追加します。警告文字列のフォーマットにより、IDEは、clang-tidyの結果がコンパイラの警告であると見なし、ソースコードにマークを付けます。また、オブジェクトファイルが作成された後、各ファイルを並行して実行します。
if ( CMAKE_VERSION GREATER "3.5" )
set(ENABLE_CLANG_TIDY OFF CACHE BOOL "Add clang-tidy automatically to builds")
if (ENABLE_CLANG_TIDY)
find_program (CLANG_TIDY_EXE NAMES "clang-tidy" PATHS /usr/local/opt/llvm/bin )
if (CLANG_TIDY_EXE)
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set(CLANG_TIDY_CHECKS "-*,modernize-*")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*'"
CACHE STRING "" FORCE)
else()
message(AUTHOR_WARNING "clang-tidy not found!")
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
endif()
endif()
endif()
これに関して私が抱えていた唯一の問題は、自動生成されたmoc_*.cxx
ファイルと、 ExternalProject
のコードからの警告の通常の煩わしさをまだチェックしていることです。
add_definitions
set CMake変数、構成段階でのみ使用可能。ビルド段階で実行されるコマンドにenvironment変数を設定する場合は、COMMAND
キーワードを使用して適切なシェルメカニズムを使用します。
add_custom_target(lint
COMMAND CMAKE_EXPORT_COMPILE_COMMANDS=ON python run-clang-tidy.py
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/run-clang-tidy.py
${CMAKE_CURRENT_BINARY_DIR}/.clang-tidy
COMMAND
キーワードに指定されたものはすべて、シェルによって「そのまま」解釈されます(CMakeの解釈後、ここでは何もしません)。