iOS静态分析:OCLint的使用

前言

OCLint是基于 Clang Tooling 开发的静态分析工具,主要用来发现编译器检查不到的那些潜在的关键技术问题。2017 年 9 月份新发布的 OCLint 0.13 版本中,包含了 71 条规则。这些规则已经基本覆盖了具有通用性的规则,主要包括语法上的基础规则、Cocoa 库相关规则、一些约定俗成的规则、各种空语句检查、是否按新语法改写的检查、命名上长变量名短变量名检查、无用的语句变量和参数的检查。

除此之外,还包括了和代码量大小是否合理相关的一些规则,比如过大的类、类里方法是否太多、参数是否过多、Block 嵌套是否太深、方法里代码是否过多、圈复杂度的检查等。你可以在官方规则索引中,查看完整的规则说明。这些规则可以在运行时被动态地加载到系统中,规则配置灵活、可扩展性好、方便自定义。

OCLint是一个通过检查C,C++或Objective-C代码来提高代码质量、降低错误率的静态代码分析工具,代码通过OCLint检测后,可以发现一些潜在的问题,如:

* 可能的bug:if/else/try/catch/finally 空语句空变量
* 代码无用:并未使用的本地变量和参数
* 代码过于复杂:高复杂度的循环、判断
* 代码冗余:冗余的if判断和多余的括号
* 代码异味:长的方法和长参数列表
* 不好的尝试:反向逻辑、参数重复赋值

静态代码分析是一个很重要的技术发现编译器中那些不可视的缺点,OCLint自动完成这些检测需要依赖以下特点:

* 依赖源代码的抽象语法树来保证精准度和效率,尽可能减少误报,避免有用的结果被跳过;
* 动态加载规则到系统中(甚至是运行期间加载规则);
* 灵活可扩展的配置保证用户可以定制化静态代码检查工具;
* 为了技术问题尽早的被修复,降低维护成本,使用命令行运行命令,在代码开发过程中,对代码进行持续集成和检测;

一、OCLint的安装

1、安装OCLint

有三种方式安装,分别为 Homebrew下载安装包安装源代码编译安装。 建议先使用Homebrew方式安装,更简单方便些。它们的区别为:

* 如果需要自定义 Lint 规则,则需要下载源码编译安装
* 如果仅仅是使用自带的规则来 Lint,那么以上3种安装方式都可以

1)Homebrew 安装 (推荐)

在安装前,确保安装了 homebrew。然后先执行brew命令安装第三方依赖库-oclint/formulae,之后再安装oclint,具体两个指令如下:

brew tap oclint/formulae
brew install oclint

安装正常完成,即证明OCLint安装成功。

2)下载安装包安装

  • 进入 OCLint 在 Github 中的地址,选择 Release。选择最新版本的安装包。
  • 解压下载文件。将文件存放到一个合适的位置。(比如我选择将这些需要的源代码存放到 Document 目录下)
  • 在终端编辑当前环境的配置文件,将 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开发。安装:

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 可以生成指定格式的数据。编译成功后,会在项目的文件夹下出现 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数据进行分析,对项目代码进行分析,最终生成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 需要静态分析的文件夹或文件 -- -report-type html -o oclintReport.html  其他的参数
  • 如有错误可根据下一小节内容进行修改,或查找其他资料解决。执行成功后,查看 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

看到报错信息是默认的警告数量超过限制,则 lint 失败。事实上 lint 后可以跟参数,所以我们修改脚本如下

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的规则

1)可以通过 -e 参数忽略指定的文件,比如忽略Pods文件夹:
oclint-json-compilation-database -e Pods -- -o=report.html
2)通过-rc改变检查规则的默认值

比如有一条默认规则:long line [size|P3] Line with 137 characters exceeds limit of 100 ,这表示一个方法里的代码行数不能超过100,可以通过-rc改变默认100行的限制比如改成200行

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

具体可以操作哪些规则,可以去官网查询

3)通过 -disable-rule可以禁止某一规则,比如禁止LongLine长方法检查:
oclint-json-compilation-database -disable-rule=LongLine
4)这些命令是可以组合使用,比如:
oclint-json-compilation-database -e Pods -rc=LONG_LINE=200-- -o=report.html
5)如果需要更改的规则比较多,可以通过.oclint 文件配置规则
具体编写规则.jpg

三、Xcode脚本使用

1、创建Aggregate项目

OClint 可以和 Xcode IDE 结合,把错误直接在 IDE 中显示出来。首先,我们在项目中创建一个新的 target,然后选择 Aggregate 作为模板。在项目的 TARGETS 下面,点击下方的 "+" ,选择 cross-platform 下面的 Aggregate。输入自定义名字,这里命名为 ZJHLint。注意我们可以建立多个 target,然后分别关注代码分析的多个方面。

创建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项目

然后我们就可以开始执行分析了,因为这里我们选择的 report-type 是 xcode,这时 oclint 发现的错误会直接在 IDE 中标示出来,方便我们对代码进行改进。当然这只是一种参考,不一定要采纳 oclint 给的提示。(我这边在Xcode运行脚本时,识别不出 xcpretty 指令,搜索了好久,还是没找到原因,这里先用了别人的截图)

lint 给的提示.png



参考链接:
OCLint 实现 Code Review - 给你的代码提提质量
OCLint在Xcode中的使用
iOS使用OCLint静态代码分析+jenkins集成
Jenkins+oclint集成iOS代码静态分析

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270