当前位置: 首页 > news >正文

使用shell脚本进行clang-tidy静态代码分析

文章目录

    • 0. 引言
    • 1. 完整检测脚本代码 clang-tidy-check.sh
      • 1.1 流程图
      • 1.2 脚本功能概述
    • 2. 该脚本优缺点

0. 引言

clang-tidy 是基于 Clang 的工具,提供了丰富的代码检查功能,可以根据用户配置文件进行定制化的检查和规则定义。
之前的文章《使用 Clang-Tidy 进行静态代码分析:完整的配置与 CMake 集成实例》已经对clang-tidy的安装和配置做了基本介绍,并指明了如何与CMake集成。
本文将介绍如何使用 shell脚本进行clang-tidy静态代码分析。

1. 完整检测脚本代码 clang-tidy-check.sh

#!/bin/bash
set -e# Default build directory
DEFAULT_BUILD_DIR="build"# Check if source dir path and optionally a build dir path are provided as arguments
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; thenecho "Usage: $0 <source_dir_path> [build_dir_path]"echo "Error: Exactly one or two arguments expected."exit 1
fi# Save the user-inputted source dir path to a variable
SOURCE_DIR="$1"# If a second argument (build directory) is provided, use it; otherwise, use the default
if [ "$#" -eq 2 ]; thenBUILD_DIR="$2"echo "$2"
elseBUILD_DIR="$DEFAULT_BUILD_DIR"echo "No build directory specified, using default: '${BUILD_DIR}'"
fi# Check if the source path is an existing directory
if [ ! -d "${SOURCE_DIR}" ]; thenecho "Error: SOURCE_DIR '${SOURCE_DIR}' does not exist."exit 1
elseecho "SOURCE_DIR is '${SOURCE_DIR}'"
fi# Optionally, you can also check if the BUILD_DIR exists or handle its absence according to your needs
if [ ! -d "${BUILD_DIR}" ]; thenecho "Warning: BUILD_DIR '${BUILD_DIR}' does not exist. Depending on your script's logic, this may or may not be a problem."
fi
############## Set the source directory and build directory
ROOT_DIR="$(pwd)"
CLANG_TIDY_CONFIG="${ROOT_DIR}/.clang-tidy"
COMPILE_COMMANDS="${BUILD_DIR}/compile_commands.json"# Check if compile_commands.json exists
if [ ! -f "${COMPILE_COMMANDS}" ]; thenecho "Error: compile_commands.json not found in ${BUILD_DIR}."exit 1
fi# Find all .cc files in the source directory recursively
ALL_STATIC_CHECK_FILES=$(find "${SOURCE_DIR}" -type f -name '*.cpp')filter_clang_tidy_output() {awk '/^clang-diagnostic-unused-command-line-argument/ {next}/^[0-9]+ warnings generated/ {next}/^Suppressed [0-9]+ warnings/ {next}/^Use -header-filter=.*$/ {next}/^Use -system-headers .*$/ {next}/\/usr\// ||/\/opt\// {skipping=1} # Start skipping upon a match with any of the specified patternsskipping == 1 && $0 ~ /\| * *\^/ {skipping=0; next} # Stop skipping when encountering the flexible patternskipping == 0 {print} # Print lines when not skipping'
}# Function to run clang-tidy
run_clang_tidy() {echo "Running clang-tidy..."for file in $ALL_STATIC_CHECK_FILES; doclang-tidy-18 "${file}" -p "${BUILD_DIR}" --warnings-as-errors=* \-config-file="${CLANG_TIDY_CONFIG}" -extra-arg=-std=c++14 \2>&1| filter_clang_tidy_output \|| touch "${BUILD_DIR}/clang_tidy_failed"done
}# Run clang-tidy
run_clang_tidy# Check the results
if [ -f "${BUILD_DIR}/clang_tidy_failed" ]; thenecho "Clang-tidy detected issues."exit 1
elseecho "No Clang-tidy issues found."
fi

1.1 流程图

合法
不合法
有指定构建目录
存在
不存在
存在
不存在
存在
不存在
有问题
无问题
开始
检查参数数量和合法性
保存源代码路径
显示错误并退出
设置默认构建目录
保存构建目录路径
显示默认构建目录
显示指定构建目录
检查源代码目录存在性
显示源代码目录路径
显示错误并退出
检查构建目录存在性
显示构建目录路径
显示警告
设置根目录和配置文件路径
检查compile_commands.json文件存在性
显示文件存在
显示错误并退出
查找所有.cpp文件
运行clang-tidy
检查clang-tidy结果
显示问题并退出
显示无问题
结束

1.2 脚本功能概述

这段脚本的主要功能包括:

  1. 检查输入参数的合法性,确保源代码目录路径正确,并根据需要指定构建目录。
  2. 检查是否存在编译命令文件 compile_commands.json,该文件是 clang-tidy 进行分析所必需的。
  3. 使用 find 命令递归查找源代码目录中的所有 .cpp 文件。
  4. 运行 clang-tidy 对每个找到的 .cpp 文件进行静态代码分析,输出详细的警告和建议。
  5. 过滤和处理 clang-tidy 的输出,以排除不必要的警告信息。
  6. 根据分析结果判断是否有代码问题,并相应地处理结果。

2. 该脚本优缺点

这段脚本的优点在于:

  • 自动化分析:有 compile_commands.json 文件即可进行分析,不用依赖CMakeLists.txt
  • 灵活处理: 可以根据分析结果,灵活地处理代码中的问题或警告,确保代码质量和稳定性。

然而,该脚本也存在一些潜在的缺点:

  • 依赖性问题: 脚本依赖于正确配置的 clang-tidycompile_commands.json 文件,因为不像CMake每次可以实时更新 compile_commands.json 文件,如果配置不正确可能导致分析失败。
  • 效率问题: 因为是依次遍历列表中的文件,对大型代码库进行全面的静态分析可能会消耗较多的时间和计算资源,影响效率。

相关文章:

  • 【鸿蒙学习笔记】基础组件 Button
  • 可重入锁思想,设计MQ迁移方案
  • 高考文化课|高三这些高效学习方法你了解了吗?
  • adb热更新
  • SpringMVC的基本使用
  • Spring Data与多数据源配置
  • 《昇思25天学习打卡营第9天|onereal》
  • adb shell logcat -b all|grep如何可以grep两个子串?
  • Rust Eq 和 PartialEq
  • 第三节:如何理解Spring的两个特性IOC和AOP(自学Spring boot 3.x第一天)
  • 嵌入式学习(Day 51:ARM指令/汇编与c语言函数相互调用)
  • 红酒SPA:享受放松与奢华的很好结合
  • (四)opengl函数加载和错误处理
  • 【RNN练习】LSTM-火灾温度预测
  • 【软考论文】论基于架构的软件设计方法及应用(ABSD)
  • Android优雅地处理按钮重复点击
  • AngularJS指令开发(1)——参数详解
  • Docker容器管理
  • es6--symbol
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • k个最大的数及变种小结
  • node入门
  • php的插入排序,通过双层for循环
  • springMvc学习笔记(2)
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 驱动程序原理
  • 如何使用 JavaScript 解析 URL
  • 入门级的git使用指北
  • 使用API自动生成工具优化前端工作流
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 数组大概知多少
  • 白色的风信子
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 2017年360最后一道编程题
  • 7行Python代码的人脸识别
  • ###C语言程序设计-----C语言学习(6)#
  • #define与typedef区别
  • #WEB前端(HTML属性)
  • (1)svelte 教程:hello world
  • (C语言)fgets与fputs函数详解
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (超详细)语音信号处理之特征提取
  • (力扣)循环队列的实现与详解(C语言)
  • (七)c52学习之旅-中断
  • (译)2019年前端性能优化清单 — 下篇
  • (原)本想说脏话,奈何已放下
  • (转)Oracle存储过程编写经验和优化措施
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .cfg\.dat\.mak(持续补充)
  • .naturalWidth 和naturalHeight属性,
  • .NET 4.0中的泛型协变和反变
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008