iOS靜態(tài)分析:OCLint的使用

前言

OCLint是基于 Clang Tooling 開發(fā)的靜態(tài)分析工具,主要用來發(fā)現(xiàn)編譯器檢查不到的那些潛在的關鍵技術問題埠褪。2017 年 9 月份新發(fā)布的 OCLint 0.13 版本中,包含了 71 條規(guī)則。這些規(guī)則已經基本覆蓋了具有通用性的規(guī)則磅轻,主要包括語法上的基礎規(guī)則、Cocoa 庫相關規(guī)則逐虚、一些約定俗成的規(guī)則聋溜、各種空語句檢查、是否按新語法改寫的檢查叭爱、命名上長變量名短變量名檢查撮躁、無用的語句變量和參數(shù)的檢查。

除此之外买雾,還包括了和代碼量大小是否合理相關的一些規(guī)則把曼,比如過大的類、類里方法是否太多漓穿、參數(shù)是否過多嗤军、Block 嵌套是否太深、方法里代碼是否過多晃危、圈復雜度的檢查等叙赚。你可以在官方規(guī)則索引中,查看完整的規(guī)則說明僚饭。這些規(guī)則可以在運行時被動態(tài)地加載到系統(tǒng)中震叮,規(guī)則配置靈活、可擴展性好鳍鸵、方便自定義苇瓣。

OCLint是一個通過檢查C,C++或Objective-C代碼來提高代碼質量、降低錯誤率的靜態(tài)代碼分析工具权纤,代碼通過OCLint檢測后钓简,可以發(fā)現(xiàn)一些潛在的問題乌妒,如:

* 可能的bug:if/else/try/catch/finally 空語句空變量
* 代碼無用:并未使用的本地變量和參數(shù)
* 代碼過于復雜:高復雜度的循環(huán)、判斷
* 代碼冗余:冗余的if判斷和多余的括號
* 代碼異味:長的方法和長參數(shù)列表
* 不好的嘗試:反向邏輯外邓、參數(shù)重復賦值

靜態(tài)代碼分析是一個很重要的技術發(fā)現(xiàn)編譯器中那些不可視的缺點撤蚊,OCLint自動完成這些檢測需要依賴以下特點:

* 依賴源代碼的抽象語法樹來保證精準度和效率,盡可能減少誤報损话,避免有用的結果被跳過侦啸;
* 動態(tài)加載規(guī)則到系統(tǒng)中(甚至是運行期間加載規(guī)則);
* 靈活可擴展的配置保證用戶可以定制化靜態(tài)代碼檢查工具丧枪;
* 為了技術問題盡早的被修復光涂,降低維護成本,使用命令行運行命令拧烦,在代碼開發(fā)過程中忘闻,對代碼進行持續(xù)集成和檢測;

一恋博、OCLint的安裝

1齐佳、安裝OCLint

有三種方式安裝,分別為 Homebrew债沮、下載安裝包安裝炼吴、源代碼編譯安裝。 建議先使用Homebrew方式安裝疫衩,更簡單方便些硅蹦。它們的區(qū)別為:

* 如果需要自定義 Lint 規(guī)則,則需要下載源碼編譯安裝
* 如果僅僅是使用自帶的規(guī)則來 Lint闷煤,那么以上3種安裝方式都可以

1)Homebrew 安裝 (推薦)

在安裝前童芹,確保安裝了 homebrew。然后先執(zhí)行brew命令安裝第三方依賴庫-oclint/formulae曹傀,之后再安裝oclint辐脖,具體兩個指令如下:

brew tap oclint/formulae
brew install oclint

安裝正常完成,即證明OCLint安裝成功皆愉。

2)下載安裝包安裝

  • 進入 OCLint 在 Github 中的地址嗜价,選擇 Release。選擇最新版本的安裝包幕庐。
  • 解壓下載文件久锥。將文件存放到一個合適的位置。(比如我選擇將這些需要的源代碼存放到 Document 目錄下)
  • 在終端編輯當前環(huán)境的配置文件异剥,將 bin 目錄添加到 PATH 下瑟由,編輯 .bashrc.bash_profile
OCLint_PATH=/Users/zjh48/Documents/oclint/build/oclint-release
export PATH=$OCLint_PATH/bin:$PATH
  • 將配置文件 source 一下。
source .bash_profile
  • 驗證是否安裝成功冤寿。在終端輸入 oclint --version

2歹苦、安裝xcodebuild

xcodebuild是xcode的編譯命令青伤,xcode 下載安裝好就已經成功安裝了,無需額外安裝

3殴瘦、安裝xcpretty

需要使用OCLint對日志信息進行分析運行命令狠角,安裝xcpretty,使用xcpretty命令分析日志信息蚪腋。xcpretty是用來格式化xcodebuild輸出的工具丰歌,使用ruby開發(fā)。安裝:

gem install xcpretty

二屉凯、OCLint命令行使用

1立帖、進入指定項目

cd /Users/zjh48/Desktop/ZJHAnalyzeDemo

2、查看項目基本信息

xcodebuild -list

打印輸出

Information about project "ZJHAnalyzeDemo":
    Targets:
        ZJHAnalyzeDemo

    Build Configurations:
        Debug
        Release

    If no build configuration is specified and -scheme is not passed then "Release" is used.

    Schemes:
        ZJHAnalyzeDemo

3悠砚、編譯項目

先clean指定項目ZJHAnalyzeDemo晓勇,因為集成了pod,所以使用ZJHAnalyzeDemo.xcworkspace灌旧;然后再Debug 編譯項目了宵蕉;最后通過xcpretty,使用 -r json-compilation-database 可以生成指定格式的數(shù)據(jù)节榜。編譯成功后,會在項目的文件夾下出現(xiàn) compile_commands.json 文件

xcodebuild -scheme ZJHAnalyzeDemo -workspace ZJHAnalyzeDemo.xcworkspace clean && xcodebuild -scheme ZJHAnalyzeDemo -workspace ZJHAnalyzeDemo.xcworkspace -configuration Debug | xcpretty -r json-compilation-database -o compile_commands.json

注意項

  • 如果項目使用了 Cocopod别智,則需要指定 -workspace xxx.workspace
  • 每次編譯之前需要 clean

4宗苍、生成 html 報表

  • 使用 oclint-json-compilation-database 命令對上一步生成的json數(shù)據(jù)進行分析,對項目代碼進行分析薄榛,最終生成report.html文件讳窟。OCLint目前支持輸出html,json敞恋,xml丽啡,pmd,Xcode格式文件
 oclint-json-compilation-database -e Pods -- -report-type html -o oclintReport.html
  • 看到有報錯硬猫,但是報錯信息太多了补箍,不好定位,利用下面的腳本則可以將報錯信息寫入 log 文件啸蜜,方便查看
oclint-json-compilation-database -e Pods -- -report-type html -o oclintReport.html 2>&1 | tee 1.log
  • 如果項目工程太大坑雅,整個 lint 會比較耗時,所幸 oclint 支持針對某個代碼文件夾進行 lint
oclint-json-compilation-database -i 需要靜態(tài)分析的文件夾或文件 -- -report-type html -o oclintReport.html  其他的參數(shù)
  • 如有錯誤可根據(jù)下一小節(jié)內容進行修改衬横,或查找其他資料解決裹粤。執(zhí)行成功后,查看 html 文件可以具體定位哪個代碼文件蜂林,哪一行哪一列有什么問題遥诉,方便修改
查看 oclintReport.html 文件.png

5拇泣、可能遇到的問題

1)報錯:oclint: error: one compiler command contains multiple jobs

報錯信息是:oclint: error: one compiler command contains multiple jobs: 查找資料:https://github.com/oclint/oclint/issues/462 解決方案如下

  • 將 Project 和 Targets 中 Building Settings 下的 COMPILER_INDEX_STORE_ENABLE 設置為 NO
COMPILER_INDEX_STORE_ENABLE 設置為 NO.png
  • 在 podfile 中 target 'xx' do 前面添加下面的腳本
post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['COMPILER_INDEX_STORE_ENABLE'] = "NO"
        end
    end
end
在 podfile 中 target 'xx' do 前面添加下面的腳本.png

2)報錯:oclint: error: violations exceed threshold

看到報錯信息是默認的警告數(shù)量超過限制,則 lint 失敗矮锈。事實上 lint 后可以跟參數(shù)霉翔,所以我們修改腳本如下

oclint-json-compilation-database -e Pods -- -report-type html -o oclintReport.html -rc LONG_LINE=9999 -max-priority-1=9999 -max-priority-2=9999 -max-priority-3=9999

6、OCLint的規(guī)則

1)可以通過 -e 參數(shù)忽略指定的文件愕难,比如忽略Pods文件夾:
oclint-json-compilation-database -e Pods -- -o=report.html
2)通過-rc改變檢查規(guī)則的默認值

比如有一條默認規(guī)則:long line [size|P3] Line with 137 characters exceeds limit of 100 早龟,這表示一個方法里的代碼行數(shù)不能超過100,可以通過-rc改變默認100行的限制比如改成200行

oclint-json-compilation-database -- -rc=LONG_LINE=200 -o=report.html

具體可以操作哪些規(guī)則猫缭,可以去官網查詢

3)通過 -disable-rule可以禁止某一規(guī)則,比如禁止LongLine長方法檢查:
oclint-json-compilation-database -disable-rule=LongLine
4)這些命令是可以組合使用葱弟,比如:
oclint-json-compilation-database -e Pods -rc=LONG_LINE=200-- -o=report.html
5)如果需要更改的規(guī)則比較多,可以通過.oclint 文件配置規(guī)則
具體編寫規(guī)則.jpg

三猜丹、Xcode腳本使用

1芝加、創(chuàng)建Aggregate項目

OClint 可以和 Xcode IDE 結合,把錯誤直接在 IDE 中顯示出來射窒。首先藏杖,我們在項目中創(chuàng)建一個新的 target,然后選擇 Aggregate 作為模板脉顿。在項目的 TARGETS 下面蝌麸,點擊下方的 "+" ,選擇 cross-platform 下面的 Aggregate艾疟。輸入自定義名字来吩,這里命名為 ZJHLint。注意我們可以建立多個 target蔽莱,然后分別關注代碼分析的多個方面弟疆。

創(chuàng)建Aggregate項目.png

2、添加 Run Script 腳本

選擇對應的 TARGET -> ZJHLint盗冷。然后在 Build Phases 選項卡中選擇 Add Run Script怠苔。

添加 Run Script 腳本.png

關于腳本的編寫我們仍然選擇最簡單的方式,即 xcodebuild + xcpretty + oclint-json-compilation-database 的方式來做 oclint仪糖。腳本如下:

cd ${SRCROOT}
xcodebuild -scheme ZJHAnalyzeDemo -workspace ZJHAnalyzeDemo.xcworkspace clean && xcodebuild -scheme ZJHAnalyzeDemo -workspace ZJHAnalyzeDemo.xcworkspace -configuration Debug | xcpretty -r json-compilation-database -o compile_commands.json && oclint-json-compilation-database -e Pods -- -report-type Xcode

3柑司、運行Aggregate項目

然后我們就可以開始執(zhí)行分析了,因為這里我們選擇的 report-type 是 xcode锅劝,這時 oclint 發(fā)現(xiàn)的錯誤會直接在 IDE 中標示出來帜羊,方便我們對代碼進行改進。當然這只是一種參考鸠天,不一定要采納 oclint 給的提示讼育。(我這邊在Xcode運行腳本時,識別不出 xcpretty 指令,搜索了好久奶段,還是沒找到原因饥瓷,這里先用了別人的截圖)

lint 給的提示.png



參考鏈接:
OCLint 實現(xiàn) Code Review - 給你的代碼提提質量
OCLint在Xcode中的使用
iOS使用OCLint靜態(tài)代碼分析+jenkins集成
Jenkins+oclint集成iOS代碼靜態(tài)分析

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市痹籍,隨后出現(xiàn)的幾起案子呢铆,更是在濱河造成了極大的恐慌,老刑警劉巖蹲缠,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棺克,死亡現(xiàn)場離奇詭異,居然都是意外死亡线定,警方通過查閱死者的電腦和手機娜谊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斤讥,“玉大人纱皆,你說我怎么就攤上這事“派蹋” “怎么了派草?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铛楣。 經常有香客問我近迁,道長,這世上最難降的妖魔是什么簸州? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任钳踊,我火速辦了婚禮,結果婚禮上勿侯,老公的妹妹穿的比我還像新娘。我一直安慰自己缴罗,他們只是感情好助琐,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著面氓,像睡著了一般兵钮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舌界,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天掘譬,我揣著相機與錄音,去河邊找鬼呻拌。 笑死葱轩,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播靴拱,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼垃喊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袜炕?” 一聲冷哼從身側響起本谜,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎偎窘,沒想到半個月后乌助,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡陌知,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年他托,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纵诞。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡上祈,死狀恐怖,靈堂內的尸體忽然破棺而出浙芙,到底是詐尸還是另有隱情登刺,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布嗡呼,位于F島的核電站纸俭,受9級特大地震影響,放射性物質發(fā)生泄漏南窗。R本人自食惡果不足惜揍很,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧举哟,春花似錦喳篇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虹钮。三九已至聋庵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芙粱,已是汗流浹背祭玉。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留春畔,地道東北人脱货。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓岛都,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹭劈。 傳聞我的和親對象是個殘疾皇子疗绣,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348