cmake clang-tidy(或其他脚本)作为自定义目标

fuj*_*uji 13 lint cmake clang target clang-tidy

我正在尝试为clang-tidy创建一个自定义cmake目标,以便对我的项目进行lint.源文件夹看起来像这样:

src/scripts/run-clang-tidy.py
src/.clang-tidy
src/...
Run Code Online (Sandbox Code Playgroud)

到目前为止,我的计划是使用自定义命令将这两个文件复制到构建目录:

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 Code Online (Sandbox Code Playgroud)

我现在想要run-clang-tidy.py在构建目录(应该是工作目录)中调用自定义目标,以便我可以调用:

make lint
Run Code Online (Sandbox Code Playgroud)

哪个应该运行指定的检查.clang-tidy.

要使此脚本起作用,它还需要该CMAKE_EXPORT_COMPILE_COMMANDS选项.我尝试使用以下命令设置它,但它无法识别它:

add_definitions(-DCMAKE_EXPORT_COMPILE_COMMANDS=ON)
Run Code Online (Sandbox Code Playgroud)

电话add_custom_target怎么样?

Ale*_*aev 24

由于CMake的3.6,的本地集成clang-tidy实现[ 1,2 ].include-what-you-use从CMake 3.3开始,力学与集成相似[ 3 ].

  • 看起来这仅适用于 makefile 和 ninja 生成器,不适用于 XCode 或 Visual Studio。所以,没有我希望的那么有帮助。 (2认同)

per*_*ror 11

我可以建议另一种方法,不需要额外的Python脚本.

首先,我希望集成clang-tidyclang-format定制CMake的规则,所以我第一次产生.clang-tidy.clang-format它是位于项目的根目录下的文件.

生成配置文件

要生成.clang-tidy,首先找到适合您项目的选项,然后执行以下操作:

$> clang-tidy <source-files> -dump-config <tidy-options> -- <compile-options> > .clang-tidy
Run Code Online (Sandbox Code Playgroud)

同样,clang-format您可以使用该-style=xxx选项以默认样式开始,然后将其转储.例如,从LLVM样式开始:

$> clang-format -style=LLVM -dump-config > .clang-format
Run Code Online (Sandbox Code Playgroud)

然后,编辑它并根据需要正确配置它.看起来应该是这样的:

---
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
...
Run Code Online (Sandbox Code Playgroud)

创建自定义CMake规则

CMake允许以非常简单的方式定义自定义规则,您只需在文件中编写一组CMake命令并调用该add_custom_target()过程,然后将其包含在您的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}
)
Run Code Online (Sandbox Code Playgroud)

然后,编辑CMakeLists.txt并添加:

# Including extra cmake rules
include(cmake/clang-dev-tools.cmake)
Run Code Online (Sandbox Code Playgroud)

然后,一旦构建系统重新生成,您应该能够运行make clang-tidymake clang-format.

  • 有同样的问题,cmake规则中缺少一个参数,它应该是`-I${INCLUDE_DIRECTORIES}`而不是`${INCLUDE_DIRECTORIES}` (2认同)

Pet*_*son 6

亚历山大·舒卡耶夫Alexander Shukaev)提到的文档在细节上有些短,所以我添加一个示例。警告字符串的格式使IDE认为整洁的结果是编译器警告,并将标记源代码。同样,在创建其目标文件后,它将并行运行每个文件。

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()
Run Code Online (Sandbox Code Playgroud)

我遇到的唯一问题是,它仍然会检查自动生成的moc_*.cxx文件以及来自的代码中常见的警告警告ExternalProject