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

时间:2015-08-28 22:36:08

标签: cmake clang target lint clang-tidy

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

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的调用怎么样?

4 个答案:

答案 0 :(得分:21)

自CMake 3.6起,clang-tidy的原生集成已实施[12]。机制与CMake 3.3 [3]之后的include-what-you-use集成类似。

答案 1 :(得分:10)

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

首先,我想在自定义CMake规则中集成clang-tidyclang-format,因此我首先生成了位于根目录下的.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规则

CMake允许以非常简单的方式定义自定义规则,您只需要通过调用add_custom_target()过程在文件中编写一组CMake命令,然后将其包含在{{1文件。这就是我们要做的,我们首先在项目的根目录创建一个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

答案 2 :(得分:5)

Alexander Shukaev提到的文档有点细节,所以我添加了一个例子。警告字符串的格式化使IDE认为铿锵有力的结果是编译器警告,并将标记源代码。此外,它在创建目标文件后并行运行每个文件。

public class Foo {
    public static void main (String[] args) {

        int[] values = {1,2,3};  //1

        int[] list = new int[3];  //2
        list[0] = 1;
        list[1] = 2;
        list[2] = 3;
    }
}

我遇到的唯一问题是,它仍会检查自动生成的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() 个文件以及ExternalProject中代码的常见警告烦恼。

答案 3 :(得分:3)

add_definitions设置 CMake 变量,仅限配置阶段。如果要为构建阶段执行的命令设置 environment 变量,请使用COMMAND关键字的相应shell机制:

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关键字指定的所有内容都将由shell“按原样”解释(在解释CMake之后,这里是no-op)。