目录
- 构建
- 代码风格
- 代码覆盖率
- 静态检测
CI构建可以分为几个部分:构建代码(可以是多个平台)——>UT用例 ——> 代码覆盖率 ——> 代码静态检测
首先保证有可以CMakeLists.txt可以在本地正常编译业务代码和UT代码
构建
首先需要有ci构建的配置文件,以gitlab为例,需要.gitlab-ci.yml的配置文件,内容和格式如下:
image: makeappdev/cpp-dev # Docker image available at https://hub.docker.comstages:                        # 配置pipeline的阶段- build                      # 阶段1: 构建- test                       # 阶段2: 测试code_build:                    # 一个单一job的pipelinestage: build                 # Stage of the jobscript:                      # Main step of the job- cmake -H. -Bbuild        # 创建build目录,并运行生成cmake文件- cmake --build ./build    # 运行cmake进行编译- make test                # 运行所有unit test
cmake的具体命令如指定编译线程数等,可以在CMake之命令行中查看
配置这个yml之后gitlab可以运行pipeline了。
代码风格
代码风格可以使用clang-format检查。
- 首先安装clang-format工具:sudo apt install clang-format;
- 编写 .clang-format文件:
---
Language:        Cpp
# BasedOnStyle:  Google
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands:   true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:   AfterClass:      falseAfterControlStatement: falseAfterEnum:       falseAfterFunction:   falseAfterNamespace:  falseAfterObjCDeclaration: falseAfterStruct:     falseAfterUnion:      falseAfterExternBlock: falseBeforeCatch:     falseBeforeElse:      falseIndentBraces:    falseSplitEmptyFunction: trueSplitEmptyRecord: trueSplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
# BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit:     80
CommentPragmas:  '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat:   false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:   - foreach- Q_FOREACH- BOOST_FOREACH
IncludeBlocks:   Preserve
IncludeCategories: - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'Priority:        2- Regex:           '^(<|"(gtest|gmock|isl|json)/)'Priority:        3- Regex:           '.*'Priority:        1
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth:     2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments:  true
SortIncludes:    true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles:  false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard:        Latest
TabWidth:        8
UseTab:          Never
...
indent_columns: 2
...
这个配置样式定义了很多选项如缩进宽度,换行规则,空格的使用等等。可以针对自己的需求进行修改。
代码覆盖率
- 首先需要安装lcov或gcov工具:sudo apt install lcov;要确保它们可以在执行 cmake 时被找到。
- 代码根目录下新创建cmake目录,把CodeCoverage.cmake放到该目录下,CodeCoverage.cmake是用于配置 CMake 以收集代码覆盖率的模块
- 在CMakeLists.txt中新增查找和包含CodeCoverage.cmke的代码:
# CMakeLists.txt
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(CodeCoverage)
这是CodeCoverage.cmake的一个示例,可以根据需要进行修改
- 在ci的yml文件最后加上对覆盖率的检测:
mkdir ccov        # 创建ccov用于存放生成的文件
make coverage     # 覆盖率检测
静态检测
- 首先需要安装clang-tidy工具:sudo apt install clang-tidy。Clang-Tidy 工具是一个非常强大的C++静态分析工具
- 同代码覆盖率一样,将ClangTidy.cmake放到cmake目录下
- 在CMakeLists.txt中新增一行 include(ClangTidy)
- 在根目录下放静态检测的.clang-tidy文件。
- 运行 CMake 或make 进行编译,Clang-Tidy 会在编译时运行
clang-tidy的内容大概如下:
---
Checks:          '-*,readability-*'
WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle:     none
User:            user
CheckOptions:    - key:             readability-identifier-naming.NamespaceCase value:           lower_case - key:             readability-identifier-naming.ClassCase value:           CamelCase  
...
在上述配置中:
Checks: 这一行定义了你想要运行的检查。在这个例子中,它会禁用所有检查(-*),然后仅启用 readability-* 系列的检查。
 WarningsAsErrors: 如果这里列出了任何检查,那么这些检查的警告将被视为错误。
 HeaderFilterRegex: 定义一个正则表达式,仅分析与此表达式匹配的头文件。
 AnalyzeTemporaryDtors: 定义是否分析临时析构函数。
 FormatStyle: 定义代码格式化样式。none 表示不进行代码格式化。
 User: 定义用户
 CheckOptions: 用于为特定检查指定选项。这里的例子中,它改变了命名约定规则,要求命名空间全部小写,类名使用驼峰命名。
 你可以检查 Clang-Tidy 的文档以获取更多信息和更多可用的检查:http://clang.llvm.org/extra/clang-tidy/
使用 .clang-tidy 文件可以帮助保持项目中的代码质量和一致性。