C++ 進行靜態代碼分析而不想付費 SonarQube 怎麼辦?

由於歷史遺留原因,當前產品的代碼倉庫裡遺留很多 Warning,這些 Warning 不是一時半會可以解決掉的。只有通過不斷的豐富自動化測試用例,來保障最後的質量關卡,才敢有條不紊的進行 Warining 的修復,在次之前,如何有效杜絕繼續引入更多的 Warining 是當下應該做的。

因此我想在 Pull Request 階段加入 C/C++ 的靜態代碼掃描的集成,但是很多工具只要涉及的是 C/C++ 經常都是收費的,比如這裡首選的 SonarQube,Community 版本不支持 C/C++ 代碼掃描,只有 Developer 以及 Enterprise 等付費版本才支持,在靜態代碼掃描還沒有帶來收益之前,盲目的付費只會給產品帶來更多的成本,因此決定先尋找其他開源工具來替代。

最終我選擇了 CPPCheck,主要有以下幾個原因:

  1. 這是為數不多的 C/C++ 開源靜態代碼掃描工具
  2. 可以與 Jenkins 集成,可以在 Jenkins 裡查看結果報告
  3. 支持 Jenkins Pipeline

本文記錄我調查和使用的經驗,如果您也相關的需求,提供一點參考。

安裝 Cppcheck

安裝到 Linux

<code>sudo yum install cppcheck.x86_64/<code>

其他平臺安裝請參考 cppcheck 官網

如果你在 Linux 無法通過命令一鍵安裝,也可通過下載源代碼構建 cppcheck。以下是從代碼手動構建一個 cppcheck 可執行文件的步驟

<code>cd opt && mkdir cppcheck && cd cppcheck
# 下載代碼
wget https://github.com/danmar/cppcheck/archive/1.90.tar.gz
# 解壓
tar -xvf 1.90.tar.gz
# make build
cd cppcheck-1.90
mkdir build
cd build
cmake ..cmake --build .
# link
sudo ln -s /opt/cppcheck/cppcheck-1.90/cppcheck /usr/bin/cppcheck
# 檢查是否安裝成功
which cppcheck
/usr/bin/cppcheck
cppcheck --version
Cppcheck 1.90/<code>

使用 cppcheck 靜態代碼掃描

在與 Jenkins 集成之前,先看看這個工具怎麼用。通過查閱Cppcheck 官方文檔,一般的使用如下:

<code># 例如掃描 src 下 public 和 themes 兩個目錄下的代碼將結果輸出到 cppcheck.xml
cppcheck src/public src/themes --xml 2> cppcheck.xml/<code>

Cppcheck 與 Jenkins 集成

首先,下載 Cppcheck Jenkins 插件,通過 Pipeline Syntax 生成了此代碼 publishCppcheck pattern:'cppcheck.xml'

但是在讀取 xml 文件進行報告展示時,我遇到了兩個問題:

問題1:分析 cppcheck.xml 我在有的 Linux 機器上成功,有的機器上會失敗,我懷疑是我的 JDK 版本不同所致。Jenkins JIRA 我也找到了次問題 JENKINS-60077 但目前還沒有人來解決。

我之所以沒有繼續嘗試去解決問題1,最主要的原因是它有一個對我來說是更致命的缺陷,那就是下面說的問題。

問題2: 無法通過 Cppcheck Results 報告直接查看代碼,這樣就算掃描出來了問題還需要去 git 或是本地的 IDE 上去查看具體的問題,大大降低效率。

<code># 查看代碼文件時會出錯
Can't read file: Can't access the file: file:/disk1/agent/workspace/cppcheck-ud113/src/public/dummy/err_printf.c/<code>

並且官方也相應的 Ticket 記錄了該問題 JENKINS-42613 和 JENKINS-54209,JENKINS-42613 一直在等待 merge,截止發文,都還是暫時沒有解決。

最後我發現 Warnings Next Generation 這個插件將取代整個 Jenkins 靜態分析套件,其中包含了這些插件 Android Lint, CheckStyle, Dry, FindBugs, PMD, Warnings, Static Analysis Utilities, Static Analysis Collector,最後通過 Warnings Next Generation 插件解決了報告展示的問題。

這裡可以通過 Pipeline Syntax 生成讀取報告代碼 recordIssues(tools:[codeAnalysis(pattern:'cppcheck.xml')])

更多有關 Warnings Next Generation 插件的使用,請參看文檔

最終 Pipeline 示例如下

<code>pipeline{
agent {
node {
label 'cppcheck'
customWorkspace "/agent/workspace/cppcheck"
}
}

parameters {

string(name: 'Branch', defaultValue: 'develop', description: 'Which branch do you want to do cppcheck?')
}

options {
timestamps ()
buildDiscarder(logRotator(numToKeepStr:'50'))
}

stage("Checkout"){
steps{
checkout([$class: 'GitSCM', branches: [[name: '*/${Branch}']],
browser: [$class: 'BitbucketWeb', repoUrl: 'https://git.yourcompany.com/projects/repos/cppcheck-example/browse'],
doGenerateSubmoduleConfigurations: false, extensions: [
[$class: 'LocalBranch', localBranch: '**'], [$class: 'CheckoutOption', timeout: 30], [$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true, timeout: 30]], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'd1cbab74-823d-41aa-abb7', url: 'https://git.yourcompany.com/scm/cppcheck-example.git']]])
}
}
stage("Cppcheck"){
steps{
/> sh 'cppcheck src/public src/themes --xml 2> cppcheck.xml'
}
}
}
stage('Publish results'){
steps {
recordIssues(tools: [cppCheck(pattern: 'cppcheck.xml')])
}
}
}/<code>

報告展示

我將 CPPCheck 應用到每個 Pull Request 裡,當開發提交新的代碼時,CPPCheck 就會去掃描代碼,然後跟之前的歷史記錄做對比。CPPCheck 執行成功並生成報告,這裡會出現一個按鈕,點擊進入。


想做 C/C++ 進行靜態代碼分析而不想付費 SonarQube 怎麼辦?

CPPCheck 報告入口

打開之後就會當前分支代碼的掃結果。

想做 C/C++ 進行靜態代碼分析而不想付費 SonarQube 怎麼辦?

CPPCheck 報告儀表板

CPPCheck 有三個維度來來展示靜態代碼掃描結果:

  1. 嚴重程度分佈(Severities Distribution):這裡分為 High,Normal,Low 三種級別
  2. 參考比較(Reference Comparison):這裡會參考之前的數據進行比較,如果有新增就會顯示 New,如果是現存的就顯示為 Outstanding,如果減少了就會顯示 Fixed
  3. 歷史(History):隨著代碼的增加和修改,這裡會顯示一個歷史記錄的趨勢

注意:cppcheck 相關的 xml 是存儲在 Jenkins master 上,只有當前的 Jenkins Job 被人為刪掉,那麼 cppcheck xml 才會被刪掉。

<code>-sh-4.2$ ls -l cppcheck*
-rw-r--r-- 1 jenkins jenkins 418591 Feb 27 05:54 cppcheck-blames.xml
-rw-r--r-- 1 jenkins jenkins 219 Feb 27 05:54 cppcheck-fixed-issues.xml
-rw-r--r-- 1 jenkins jenkins 142298 Feb 27 05:54 cppcheck-forensics.xml
-rw-r--r-- 1 jenkins jenkins 219 Feb 27 05:54 cppcheck-new-issues.xml
-rw-r--r-- 1 jenkins jenkins 488636 Feb 27 05:54 cppcheck-outstanding-issues.xml/<code>
想做 C/C++ 進行靜態代碼分析而不想付費 SonarQube 怎麼辦?

CPPCheck 報告詳情

點擊相應的連接就可以直接跳轉到具體的代碼警告位置了。

它是不是還挺香的?


分享到:


相關文章: