OCLint开发环境搭建,调试与自定义走查规则

1.安装

1.1 下载源代码

直接clone https://github.com/oclint/oclint官方源代码,当然你也可选择最新realse版本。

1.2 构建编译oclint

进入oclint-scripts文件夹,执行,命令./make,此过程要点时间,执行该命令之前需要安装cmake;可能会遇到提醒安装openssl,brew install openssl;可能会遇到提醒安装ninjia,brew install ninjia。这些可能会遇到的问题,按命令行问题提示,处理掉就好,如果编译失败,将不能进入下面的步骤。

2.调试

2.1 新建脚本管理xcode工程

安装成功后,我们可以用xcode来管理,开发调试各种走查规则,且我们的每个规则都是一个scheme,编译时,可以只选择特定某规则调试,生成对应的dylib,这样编译速度快,这是我已经配置好的xcode调试工程,如图:


OCLint开发环境搭建,调试与自定义走查规则_第1张图片
image.png

新建该projcet命令:

//在OCLint源码目录下建立了一个文件夹,命名为oclint-kgclang-rules
mkdir oclint-kgclang-rules
cd oclint-kgclang-rules
cmake -G Xcode -D CMAKE_CXX_COMPILER=../build/llvm-install/bin/clang++  -D CMAKE_C_COMPILER=../build/llvm-install/bin/clang -D OCLINT_BUILD_DIR=../build/oclint-core -D OCLINT_SOURCE_DIR=../oclint-core -D OCLINT_METRICS_SOURCE_DIR=../oclint-metrics -D OCLINT_METRICS_BUILD_DIR=../build/oclint-metrics -D LLVM_ROOT=../build/llvm-install/ ../oclint-rules

那么接下来,我们就可以打开,运行该工程。你会发现里面已经集成了很多oclint开发的自定义走查脚本,这是极好的学习参考资料。具体,***/oclint/oclint-kgclang-rules目录里面有oclint已经自定义的脚本,这是一个可以build的xcode工程,但是暂时还不能调试,因我们的模板是dylib动态链接库,这些动态链接库可以一次性编译,也可以选择单个项目单独编译。如下图:


OCLint开发环境搭建,调试与自定义走查规则_第2张图片
image.png

2.1 静态走查规则的动态链接库调试

现在dylib,需要主程序来引导启动,配置如下。


OCLint开发环境搭建,调试与自定义走查规则_第3张图片
image.png

备注:启动引导工程需要用/Users/ganvinalix/oclint/build/oclint-release/bin/oclintExe ,oclintExe为oclint的拷贝。

OCLint开发环境搭建,调试与自定义走查规则_第4张图片
image.png

通过xcode配置

OCLint开发环境搭建,调试与自定义走查规则_第5张图片
image.png

选择自己拷贝的oclint编译结果oclintExe(一定要编译oclint成功后才有该文件夹)

OCLint开发环境搭建,调试与自定义走查规则_第6张图片
image.png

接下来还需要配置入口调试参数(oclint可执行文件的输入参数):

OCLint开发环境搭建,调试与自定义走查规则_第7张图片
image.png

命令如下:

-R=/Users/ganvinalix/oclint/oclint-kgclang-rules/rules.dl/Debug  /Users/ganvinalix/oclint/oclint-kgclang-rules/debug.m -- -x objective-c 

意思是,在我们自己oclint-kgclang-rules工程下新建一个调试文件debug.m。


OCLint开发环境搭建,调试与自定义走查规则_第8张图片
image.png

准备好用demo中的规则来检测我们的debug.m文件吧。
如何调试自己工程呢? 自己的工程往往文件是依赖的,所以需要把依赖信息一起作为参数传递进来。

 -R=/Users/ganvinalix/oclint/oclint-kgclang-rules/rules.dl/Debug  /Users/ganvinalix/Desktop/TestOClintProject/TestOClintProject/ViewController.m -- 
-x objective-c -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fobjc-arc -fobjc-weak -fmodules -gmodules -fmodules-cache-path=/Users/ganvinalix/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/ganvinalix/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wimplicit-retain-self -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wdeprecated-implementations -DDEBUG=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -mios-simulator-version-min=11.4 -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wunguarded-availability -fobjc-abi-version=2 -fobjc-legacy-dispatch -index-store-path /Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Index/DataStore -iquote /Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/TestOClintProject-generated-files.hmap -I/Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/TestOClintProject-own-target-headers.hmap -I/Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/TestOClintProject-all-target-headers.hmap -iquote /Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/TestOClintProject-project-headers.hmap -I/Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Products/Debug-iphonesimulator/include -I/Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/DerivedSources/x86_64 -I/Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/DerivedSources -F/Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Products/Debug-iphonesimulator -MMD -MT dependencies -MF /Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/Objects-normal/x86_64/ViewController.d --serialize-diagnostics /Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/Objects-normal/x86_64/ViewController.dia -c /Users/ganvinalix/Desktop/TestOClintProject/TestOClintProject/ViewController.m -o /Users/ganvinalix/Library/Developer/Xcode/DerivedData/TestOClintProject-dborgnvcnbtwmndeqnvmjirynvrt/Build/Intermediates.noindex/TestOClintProject.build/Debug-iphonesimulator/TestOClintProject.build/Objects-normal/x86_64/ViewController.o

这么长,哪里来的?其实就是我们用xcode build的build log信息,上面的例子是调试我demo工程TestOClintProject下的ViewControlle.m文件,实际开发中是需要调试走查的特定项目的工程文件,可以说项目里面的任何其中一个.m文件都是有很多代码库依赖的,所以需要把所有的build信息包进来。


OCLint开发环境搭建,调试与自定义走查规则_第9张图片
image.png

2.2 自定义静态代码走查规则

之前我们是用oclint-kgclang-rules已有的子项目调试运行。现在我们自己新增子项目。新增步骤如下,
A.如何新增子项目
以我的一个走查脚本为例,生成一个名为ViewCtrlMustHavePageID类型是ASTVisitor的规则模板,oclint根目录执行命令

oclint-scripts/scaffoldRule ViewCtrlMustHavePageID  -t ASTVisitor

执行后会在/Users/ganvinalix/oclint/oclint-rules/rules/custom/下生产我们自己定义的插件脚本,以cmake管理的,如果不懂cmake可以先不用理会它。


OCLint开发环境搭建,调试与自定义走查规则_第10张图片
image.png

然后回到我们的oclint-kgclang-rules oc工程下,重新执行命令,

#! /bin/sh -e
cmake -G Xcode -D CMAKE_CXX_COMPILER=../build/llvm-install/bin/clang++  -D CMAKE_C_COMPILER=../build/llvm-install/bin/clang -D OCLINT_BUILD_DIR=../build/oclint-core -D OCLINT_SOURCE_DIR=../oclint-core -D OCLINT_METRICS_SOURCE_DIR=../oclint-metrics -D OCLINT_METRICS_BUILD_DIR=../build/oclint-metrics -D LLVM_ROOT=../build/llvm-install/ ../oclint-rules

建议上面命令改成.sh脚本文件方便调用,如我的:/Users/ganvinalix/oclint/oclint-kgclang-rules/create-xcode-rules.sh ,一切顺利的话能看到:


OCLint开发环境搭建,调试与自定义走查规则_第11张图片
image.png

重新打开之前创建的OC工程,可以看到子项目已经新增成功了。


image.png

按步骤2.1,给我们新增的子项目,也配上调试参数。到这里,你的oclint已经能调试了。但是如果不了解AST,还是看不懂源的代码,也无法顺利完成走查需求的。当然如已经铺好,到达目的地,只是时间的问题。

3 AST简易介绍.

3.1 一个很重的命令

把我们的工程文件dump成为ast文件,查看dump结果。我的开发习惯是,接到一个走查需求,一定dump对应的目标文件,形成思路后,再实现走查代码。

clang -Xclang -ast-dump -fsyntax-only ./testOCLint/main.m

这样就够了?这么简单,肯定是不行的,在实际开发中,是需要传入各种各样的编译环境依赖的.如开发平台上面的,arc等编译控制项!


OCLint开发环境搭建,调试与自定义走查规则_第12张图片
image.png

这样一大段也是从Xcode build log中导出的,不是全部,自己参照着来获取部分有用的 build log,这样就能dump自己的业务文件了!


OCLint开发环境搭建,调试与自定义走查规则_第13张图片
image.png

dump的AST语法图谱:
OCLint开发环境搭建,调试与自定义走查规则_第14张图片
image.png

简单的调试,可以用oclint-kgclang-rules里面的debug.m,开发调试的。

后续

16年的时候就写了若干插件,时间一久容易忘记,打算再写若干篇文章,记录怎么用AST,最终能尽情的编写clang静态代码走查插件,也让自己随时翻阅!

喜欢的朋友帮忙点个赞!!!

你可能感兴趣的:(OCLint开发环境搭建,调试与自定义走查规则)