iOS代码静态分析平台搭建(一)之OCLint集成

前言

每一个项目在一开始的时候代码都是非常规整,结构清晰明了的,但是随着项目的不断迭代,需求不断的增加,团队逐渐壮大后,慢慢我们的项目就开始出了问题,长期下来就会造成我们不愿意面对的“屎山代码”,所以制定一套代码分析系统是十分必要的。

xcodebuild

这个无需特意安装,只要电脑中有Xcode就会自带xcodebuild,使用命令行编译项目并不是什么难事,现在几乎所有的公司都采用脚本进行打包操作,如果我们要进行静态代码分析就更加的简单,只需要保证编译过程即可,OCLint的原理就是通过分析我们app的build日志来进行规范性检查,无需像打包一样考虑后续的步骤。

平时我们编写代码后编译运行都要选择对应的scheme,使用命令行编译代码也一样,cd到工程目录下,我们可以通过xcodebuild -list命令查看工程的target以及scheme还有Configurations

imac0823@imac TestDemo % xcodebuild -list
Command line invocation:
    /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -list

User defaults from command line:
    IDEPackageSupportUseBuiltinSCM = YES

Information about project "TestDemo":
    Targets:
        TestDemo
        TestDemoQ

    Build Configurations:
        Debug
        DebugPro
        Release
        ReleasePro

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

    Schemes:
        TestDemo
        TestDemoQ

在编译之前最好进行一遍clean操作,以防发生一些意外的错误,这个命令也很常见xcodebuild clean

xcodebuild clean

接下来就是选择对应的workspacescheme以及Configurations进行构建操作

xcodebuild build -scheme <your_scheme> -workspace <your_workspace>.xcworkspace -configuration Debug

这时你会发现编译可能会失败并报出以下错误

note: Building targets in dependency order
/Users/imac0823/Desktop/TestDemo/TestDemo.xcodeproj: error: Provisioning profile "iOS Team Provisioning Profile: com.xxxx.xxxxx" doesn't include the currently selected device "Xxxxx的iMac" (identifier 000000-000000A000D0000E). (in target 'TestDemoQ' from project 'TestDemo')
warning: Run script build phase 'Run Script' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'TestDemoQ' from project 'TestDemo')
** BUILD FAILED **

这是因为我们没有指定对应的编译设备导致出现问题,可以通过xcodebuild -showsdks查看可选择的编译设备

imac0823@iMac TestDemo % xcodebuild -showsdks
DriverKit SDKs:
    DriverKit 22.2                  -sdk driverkit22.2

iOS SDKs:
    iOS 16.2                        -sdk iphoneos16.2

iOS Simulator SDKs:
    Simulator - iOS 16.2            -sdk iphonesimulator16.2

macOS SDKs:
    macOS 13.1                      -sdk macosx13.1
    macOS 13.1                      -sdk macosx13.1

tvOS SDKs:
    tvOS 16.1                       -sdk appletvos16.1

tvOS Simulator SDKs:
    Simulator - tvOS 16.1           -sdk appletvsimulator16.1

watchOS SDKs:
    watchOS 9.1                     -sdk watchos9.1

watchOS Simulator SDKs:
    Simulator - watchOS 9.1         -sdk watchsimulator9.1

直接指定使用iOS SDKs进行编译即可,编译前再加上clean就是完整的编译命令

xcodebuild clean build -scheme TestDemoQ -workspace TestDemo.xcworkspace -configuration Debug -sdk iphoneos16.2

编译成功

warning: Run script build phase 'Run Script' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'TestDemoQ' from project 'TestDemo')
** BUILD SUCCEEDED **

xcpretty

命令行编译的过程中我们可以看到控制台整个日志的打印是非常杂乱无章的。
️此处需要插入图片️
xcpretty的作用就是格式化我们的build日志,让整个编译过程的日志看起来更加的清晰明了。

首先需要通过控制台进行安装

gem install xcpretty

如果安装遇到权限相关问题可以参考我的上一篇文章,安装成功之后他的使用也很简单,直接在我们编译命令后面跟上xcpretty即可

xcodebuild clean build -scheme TestDemoQ -workspace TestDemo.xcworkspace -configuration Debug -sdk iphoneos16.2 | xcpretty

使用了xcpretty之后整个打印过程就会清晰明了很多

之前说过OCLint是分析编译过程的日志来进行规范化扫描,实际上就是需要使用xcpretty格式化之后的日志,因此我们要输出格式化之后的报告。

-r //设置输出报告的格式,junit,html,json-compilation-database,推荐使用json-compilation-database
-o //输出文件的名称,必须设置为compile_commands.json,不然OCLint分析的时候会报错
️编译命令要添加COMPILER_INDEX_STORE_ENABLE=NO,OCLint分析的时候会报oclint: error: one compiler command contains multiple jobs错误

完整命令如下:

xcodebuild clean build -scheme TestDemoQ -workspace TestDemo.xcworkspace -configuration Debug COMPILER_INDEX_STORE_ENABLE=NO -sdk iphoneos16.2 | xcpretty -r json-compilation-database -o compile_commands.json

执行完命令我们的项目工程目录中就会生成一个名为compile_commands.json的文件


接下来就可以着手准备OCLint的安装了。

OCLint

OCLint 是一种静态代码分析工具,用于通过检查 C、C++ 和 Objective-C 代码并查找潜在问题来提高质量并减少缺陷,静态代码分析是检测编译器不可见的缺陷的关键技术。OCLint 通过高级功能自动执行此检查过程:

  • 依托源码的抽象语法树,准确性和效率更高;误报被减少,以避免有用的结果陷入其中。
  • 即使在运行时,也可以将规则动态加载到系统中。
  • 灵活且可扩展的配置,用户可自定义检查规则。
  • 有利于开发过程中代码的持续集成和持续检查,尽早修复技术债务,降低维护成本。

以上就是OCLint官网的说明。可以使用终端来进行OCLint的安装。

brew install oclint

也可以从GitHub官方链接下载安装。


可惜现在从官网下载安装也安装不到最新的版本了😂,它只支持到Xcode13,但是目前大家用的肯定都是Xcode14以上,如果使用官网版本去运行会报非常多的错误。因此,14以下的可以官网下载安装,14以上可以去到这个链接进行下载安装,一位大神修复了OCLint在Xcode14上的问题。

直接从链接把源码下载下来,使用终端cd到oclint-scripts文件夹下,执行./make即可,完成后找到以下内容,全部拷贝到你想要存放的路径中比如/Users/Documents/OCLint

最后配置环境变量

export PATH="/Users/Documents/OCLint/bin:$PATH"
source ~/.zshrc

输入oclint --version,查看是否配置成功

imac@iMac ~ % oclint --version
OCLint (https://oclint.org):
  OCLint version 23.0.
  Built Sep 21 2023 (16:21:47).

OCLint自带了72条检查规则,详情可以参考官方文档,使用OCLint检查代码的时候会查出来非常多不规范的内容,因此我们最好把范围缩小,比如不检查Pods目录下的第三方库,或者系统的Application文件,就可以使用-e来进行忽略。

-e Pods -e Application

也可以指定输出报告的格式

-report-type html -o oclintReport.html

完整的指令如下,在compile_commands.json目录下执行,执行完毕就会多出一个oclintReport.html文件,输出报告的时间取决于项目的大小。

oclint-json-compilation-database -e Pods -e Applications -- -report-type html -o oclintReport.html

这样的报告输出会检查出来非常多的代码不规范,我们也可以指定哪些规则不检测,或者只检测某些规则,这些留到下一篇文章去讲解。

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

推荐阅读更多精彩内容