May 13

OCLint静态检查环境搭建与使用

Lrdcq , 2016/05/13 22:54 , 教程 , 閱讀(5897) , Via 本站原創
1.oc代码静态检查方案

对于oc代码的静态检查方案,传统的,当然是Clang Static Analyzer咯。看名字就知道CSA是通吃Clang下所有代码的静态检查器。另外还有一个最常见的方案,oclint,看名字就可知,它是针对oc的类lint的静态检查器。这个并没有强大的背景,但是在强大的开源社区的帮助下,它还是非常完善的。
具体从原理上考虑,csa和oclint其实一样,都是基于clang的前端编译的。clang把我们的源码编译为了抽象语法树和llvm的字节码,而cas与oclint事实上是在对这两个东西进行分析。而分析层面上,这两者则有一些不同。

csa作为已经被xcode内置的检查器,当然用起来相当的方便,不过相对来说,csa对oc可用的检查器简直是少之又少,只有16条,而去大部分是核心向的比如空指针检测,类型转换检测,空判断检测,内存泄漏检测这种一出问题必须崩的blocker级错误,和代码风格相关的几乎没有,当然也谈不上可配置性的了。当然,也可以自己写拓展规则,当那就意味着自己改csa代码后重新编译一个——虽然可行,成本也是高得离谱了,相应的也无法灵活组织规则,可拓展性差。

而oclint呢,相对来说可用的规则多很多,七十多条呢。也可以通过命令行或者.oclint的配置文件对规则的启用禁用,参数进行调整等,方便对于不同项目进行不同配置。同时可以配置的规则除了blocker级别的检查,还有很多代码风格方面的检查,适用于不同团队灵活使用。自定义规则虽然依然得用c++来写,但是是以动态链接库储存的并且可以通过配置文件动态加载,相较于csa来说方便了很多。

当然,还有一些企业级的oc静态检查解决方案,我们当然也不再考虑。相对于眼下成本最低的两种方案,我们当然选择oclint了。

2.使用oclint对项目进行检查

oclint在github提供源码与编译好的二进制文件的下载方式(x86-linux/mac),当然linux下意义不是很大,毕竟xcode项目在非mac并不能编译(当然,不依赖iossdk的基类除外)。直接下载二进制文件好了,将其中的bin添加到环境变量中,输入oclint命令,看看能否获得结果了。
oclint直接对一个oc文件进行检查是非常方便的,只需要
oclint sample.m -- -c

后面的option跟的是编译指令,只要文件能编译过,就能进行分析了。

当然,对于一个完整的xcode项目,一方面分析当个文件是没有意义的,另一方面有ios的sdk在这样编译也编译不过啊。而xcode编译的时候,那一堆繁琐的命令,鬼才能理清楚啊。因此,oclint除了本体,有专门的工具来解决这个问题。首先我们需要把编译项目的时候的那些命令扒下来吧,还记得么,每次xcode编译的时候会log出来那些命令,整理到文件中不就好了。所以我们首先跑一下编译:
xcodebuild clean
xcodebuild -workspace xxx.xcworkspace -scheme xxx -configuration xxx | tee xcodebuild.log

这样,把编译的时候的log全部吐到xcodebuild.log文件中了。然后需要从中提取游泳池的信息,oclint提供这个:
oclint-xcodebuild

它会在当前目录下吐出整理后的数据compile_commands.json,然后用这样的方式跑oclint:
oclint-json-compilation-database  -- -report-type html -o oclintReport.html

经过一番编译运算后,以我设定的html方式将检测结果输出到了oclintReport.html下。perfect!

另外,如果当前运行的目录下存在.oclint配置文件的话,它在运行前会读取配置文件中的内容作为运行参数。里面主要可以设置的包括rule-paths(规则文件路径),disable-rules(禁用规则),max-priority-x(结果阈值设置),rule-configurations(规则参数设置)。当然,这些东西也可以跟在oclint命令后面的参数中。

除了在终端运行,也可以作为target在xcode中运行,反正就一段shell嘛。唯一不通的地方是,可以选择-report-type xcode,这样可以在运行完成之后,将结果作为warming直接在xcode中高亮提醒出来,在开发过程中比较实用。

3.踩坑

当然,这么简单的工具用起来也很方便,但是事实上往jenkins上搭的时候遇到一些问题,下面就是最值得一写的踩坑心得了。

1.重复编译:在xcodebuild对代码进行重复编译的时候,会检查代码是否已经编译过了,编译过的就不会再编译了。这本身没什么问题,但oclint检查的文件依赖编译吐的log,因此重复编译时没吐log的文件不会被编译到,也不会被静态检查到,就算每次clean工程都不行。解决方法是每次构建项目时删除原本的文件,重新clone一次新的,由于文件更新时间较新,就会被重新编译了。本地运行的话暂时无法解决。

2.oclint程序管理:由于oclint在slave机器上并没有,再切我们考虑夹带一些自己的检查规则,因此每次oclint都会是自己带过来的。现在的解决方案是用一个专门的仓库来管理oclint的bin和rules的动态链接库,虽然这样不合理,但是能比较方便的把配置好的程序clone到运行的slave上并正确的运行。

3.配置文件无法加载:在当前的运行条件下,.oclint配置文件使用无法自动加载且无法得知原因,有可能和oclint程序并没有配置到path目录导致启动目录不定有关。但是怎么将配置文件中的内容应用到程序上呢,我编写了一段辅助shell从.oclint中取出参数组装为命令在oclint命令后加入。

4.jenkins成功与归档:oclint有一个检查成功与否的阈值,如果错误数高于阈值,就会运行失败。在ci过程中可以通过设置这个值来确保ci是否通过。另外oclint最终可以输出一个特定的报告,包括html,pmd,json等常用数据格式。除了把这个文件归档,还可以使用特定的jenkins插件将数据展示到页面上或者专递到其他系统中。

5.自定义规则:由于oclint的规则还是太少不够用,并且拓展也不多,我们需要调研一下自己写规则了。调研中...
logo