iOS開發 - OCLint自定義規則的編譯與Xcode調試

OCLint的編譯

基於版本 oclint version 0.15

OCLint 需要自定義規則的話需要自己編譯,如果是簡單的使用,參考 OCLint的使用

Github下拉代碼:
git clone https://github.com/oclint/oclint

README.md
oclint-core
oclint-driver
oclint-metrics
oclint-reporters
oclint-rules
oclint-scripts

編譯過程比較長,需要 富牆 纔會快一點

過程中提示錯誤,這裏需要提前安裝 cmake 以及 Ninja

  • 安裝 cmake
  1. 官網下載CMake,傳送門:https://cmake.org/download/

  2. 命令行輸入 sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install

  3. 修改 ~/.bash_profile 文件

export CMAKE_ROOT=/Applications/CMake.app/Contents/bin/
 
export PATH=$CMAKE_ROOT:$PATH
  1. 終端運行source ~/.bash_profile使修改生效
  • 安裝 Ninjia

ninja需要依賴於re2c,否則編譯是會報錯,re2c是一款語法分析器

  1. 安裝re2c

http://re2c.org/index.html 下載 re2c

下載 re2c-1.3.tar 解壓,然後

cd re2c-1.3
./configure
make 
make install
  1. 安裝ninjia
git clone git://github.com/ninja-build/ninja.git && cd ninja
./configure.py --bootstrap
 
//mac 10.14以上版本權限可能不夠
cp ninja /usr/bin/

或者拷貝至 /Applications/CMake.app/Contents/bin/
  • 編譯OCLint

然後進入oclint-scripts,執行./make

sheng@chengpengdeMacBook-Pro oclint-scripts % ./make
Cloning into 'oclint-json-compilation-database'...
remote: Enumerating objects: 88, done.
remote: Total 88 (delta 0), reused 0 (delta 0), pack-reused 88
Unpacking objects: 100% (88/88), done.
Cloning into 'oclint-xcodebuild'...
remote: Enumerating objects: 85, done.
remote: Total 85 (delta 0), reused 0 (delta 0), pack-reused 85
Unpacking objects: 100% (85/85), done.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   657  100   657    0     0    503      0  0:00:01  0:00:01 --:--:--   503
100  424M  100  424M    0     0  4238k      0  0:01:42  0:01:42 --:--:-- 4720k

...
...
-- The C compiler identification is Clang 10.0.0
-- The CXX compiler identification is Clang 10.0.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Volumes/CaiCai/OCLint/oclint/build/llvm-install/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Volumes/CaiCai/OCLint/oclint/build/llvm-install/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
LLVM_ROOT: /Volumes/CaiCai/OCLint/oclint/build/llvm-install
-- Found LLVM LLVM_PACKAGE_VERSION: 10.0.0 - LLVM_VERSION_RELEASE: 10.0.0
-- Using LLVMConfig.cmake in: /Volumes/CaiCai/OCLint/oclint/build/llvm-install/lib/cmake/llvm
-- Configuring done
-- Generating done
-- Build files have been written to: /Volumes/CaiCai/OCLint/oclint/build/oclint-driver
[14/14] Linking CXX executable bin/oclint-0.15

到這裏OCLint算編譯成功了,但是還無法使用,參考官方文檔 installation 部分說明,我們採用直接添加進PATH方式

修改 ~/.bash_profile 文件 ,加入以下內容

OCLINT_HOME=/Users/sheng/Documents/Caicai/OCLint/oclint/build/oclint-release
export PATH=$OCLINT_HOME/bin:$PATH

然後 source ~/.bash_profile 使得修改生效

命令行輸入 oclint 進行驗證

sheng@chengpengdeMacBook-Pro ~ % oclint
LLVM ERROR: CommonOptionsParser: failed to parse command-line arguments. [CommonOptionsParser]: oclint: Not enough positional command line arguments specified!
Must specify at least 1 positional argument: See: oclint --help

這樣就算成功了

自定義規則

rule 添加

OCLint 提供了一個腳本程序,位於 oclint-scripts/scaffoldRule

通過他傳入要生成的規則名,級別,類型,腳本就會在目錄oclint-rules/rules/custom/自動幫我們生成一個模板代碼,並且加入編譯路徑中。舉個例子:

//生成一個名爲 CCRuleTest ,類型爲 ASTVisitor 的規則模板
oclint-scripts/scaffoldRule CCRuleTest -t ASTVisitor

你可以查看 scaffoldRule文件瞭解更多可配置的參數

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("class_name", help="class name of the rule")
arg_parser.add_argument("-t", "--type", dest='rule_type', choices=['Generic', 'SourceCodeReader', 'ASTVisitor', 'ASTMatcher'], default="Generic")
arg_parser.add_argument("-c", "--category", dest='rule_category', default="custom")
arg_parser.add_argument("-n", "--name", dest='rule_name', default="")
arg_parser.add_argument("-p", "--priority", type=int, dest='rule_priority', choices=[1, 2, 3], default=3)
arg_parser.add_argument(      "--test",    dest='generate_tests', action='store_true',  help="Generate a test for the new rule (default)")
arg_parser.add_argument(      "--no-test", dest='generate_tests', action='store_false', help="Do not generate a test for the new rule")
arg_parser.set_defaults(generate_tests=True)
args = arg_parser.parse_args()

這樣就會在 oclint/oclint-rules/rules/custom 路勁下生成對應的文件

在這裏插入圖片描述

cpp文件是邏輯實現,txt文件是規則匹配

Xcode工程創建

我們通過生成xcode工程來直觀的管理各個規則,包括我們新建的ruleOCLint工程使用CMakeLists的方式維護各個文件的依賴關係,我們可以使用CMake自帶的功能將這些CMakeLists生成一個xcodeproj工程文件

  • OCLint源碼目錄下建立一個文件夾,命名爲oclint-xcoderules

在這裏插入圖片描述

並創建一個腳本 ./create-xcode-rules.sh ,鍵入內容如下:

#! /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 create-xcode-rules.sh 運行腳本,就生成了我們的xcode工程 OCLINT_RULES

打開工程我們可以發現創建的rule在裏面

在這裏插入圖片描述

如果使用brew安裝,這個路徑應該是 /usr/local/Cellar/oclint/0.15/lib/oclint/rules

編譯會生成對應的dylib庫,那我們之後如何更新 OCLint 的規則呢

更新dylib

oclint/build/oclint-release 是最終編輯結果,當我們添加了自定義規則後,自然要將自定義規則添加到oclint-release 中,我們進入 oclint/build/oclint-release/lib/oclint/rules ,可以看到所有的規則dylib都放在這裏,我們將編譯後的dylib放進來,就可以了

在這裏插入圖片描述
這樣命令行調用 oclint 命令就會應用該rule,但是問題來了,我們如何調試呢,能夠在Xcode裏面進行調試最好,不然每次編譯,然後查看結果,要崩潰了。

Xcode調試

cd 進入 oclint-driver 目錄下,參考之前的方式,創建 Xcode工程

  1. 創建 create-xcode-driver.sh
  2. 腳本內容如下
#! /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-driver

你可以每個文件夾生成Xcode工程,修改最後一個參數
這裏對 oclint-driver 生成Xcode工程

  1. 執行腳本 sh create-xcode-driver.sh,生成 Xcode工程

  2. 打開 Schemes 面板,配置 啓動參數

-R=/Users/sheng/Documents/Caicai/OCLint/oclint/oclint-xcoderules/rules.dl/Debug -report-type html -o /Users/sheng/Documents/Caicai/OCLint/oclint/output/reporter.html /Users/sheng/Documents/Caicai/OCLint/oclint/demo/test.m -- -x objective-c -isystem /Users/sheng/Documents/Caicai/OCLint/oclint/build/oclint-release/lib/clang/10.0.0/include -iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks -isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include

-R 表示設置rule的路徑,我們設置爲rule工程的編譯debug路徑
-report-type html -o html文件報告輸出路徑
test.m 我們寫一個本地變量未使用的rule檢測

int main(void) {
    int i=9;
    return 0;
}


見下圖:
在這裏插入圖片描述

  • 拷貝reporters文件

設置運行後,終端打印錯誤

oclint: error: cannot find dynamic library for report type: html
Program ended with exit code: 2

搜索錯誤 cannot find dynamic library 斷點查看 reportDirPath 值爲

/Users/sheng/Documents/Caicai/OCLint/oclint/oclint-driver/bin/Debug/../lib/oclint/reporters

因爲我們改了bin的路徑,它根據 bin路徑/../lib/oclint/reporters 來查找 reporters ,這裏直接將 oclint-release 下的 reporters 連父目錄一起拷貝,構成這個路徑


  • 創建reporter.html

再次運行提示錯誤

oclint: error: cannot open report output file /Users/sheng/Documents/Caicai/OCLint/oclint/output/reporter.html
Program ended with exit code: 4

這裏是創建的 output 文件夾路徑寫錯了,放置到上面所說的正確位置後運行正常

運行正常後,查看 reporter.html

在這裏插入圖片描述

然後進行斷點 UnusedLocalVariableRule.cpp 來進行調試

在這裏插入圖片描述

成功斷點,之後你就可以自行編寫 rule,並進行調試了

參考文章: https://www.jianshu.com/p/84fa7b8fd8fe

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章