问题描述

我们的项目持续集成与交付采用的方案是Jenkins, iOS项目采用Object-C作为开发语言

整个持续集成与交付过程分为: 初始化项目 → 单元测试 → 代码检查 → 打包 → 部署这几个环节

升级Xcode 11后, 在持续集成SonarQube环节, 执行OCLint分析环节(第二步执行oclint-json-compilation-database时)抛出异常, 返回错误码6, 导致持续集成失败

通过本地终端调试, 一般遇到的错误有:

  • 一个或多个X error generated

  • oclint:error:cannot open report outputfile oclint.xml

  • 偶尔生成了PMD文件, 里面发现会带有苹果SDK的信息, 如/Applications/Xcode.app/Contents/Developer/Platforms/...路径下

问题分析

首先将持续集成中代码检查这一环节按照工具链拆分成以下步骤:

  1. 执行xcodebuildtee指令采集xcodebuild.log文件
  2. 通过xcprettyxcodebuild.log文件做格式化处理
  3. 通过OCLintjson-compilation-database工具将xcodebuild.log文件编译生成JSON Compilation Database Format格式的compile_commands.json文件
  4. 执行OCLintoclint-json-compilation-database工具从compile_commands.json文件中提取必要信息, 生成jenkins识别的PMD格式文件
  5. 执行SonarQube处理

目前是在执行步骤4的时候出现了错误, 怀疑是步骤3步骤4OCLint某一个环节出错, 最终查看官方issues, 可以确认为OCLint 0.13.0LLVM版本过低, 需要升级OCLint

homebrew当前最高可用版本为0.13, 正是目前所使用的版本:

  • $ oclint --version

    LLVM (http://llvm.org/):
      LLVM version 5.0.0svn-r313528
      Optimized build.
      Default target: x86_64-apple-darwin19.4.0
      Host CPU: skylake
    
      OCLint (http://oclint.org/):
      OCLint version 0.13.
      Built Sep 18 2017 (08:58:40).
    
  • 在这之后, 其实还有0.13.10.140.15版本, 0.140.15目前只能通过编译安装

终端科学上网, 编译安装过程简介

一 通过homebrew安装cmakeNinja两个编译工具

$ brew install cmake ninja

二 本地编译安装OCLint 0.15.0

  1. Clone OCLint SourceCode
  2. cdoclint-scripts路径下
  3. 执行./make, 成功之后会出现build文件夹, oclint-release就是编译成功的OCLint工具
  4. 设置OCLint工具的环境变量:

    • 添加环境

        OCLint_PATH=换成你存放的实际路径/oclint/build/oclint-release
        export PATH=$OCLint_PATH/bin:$PATH
      
    • 更新环境

      执行source ~/.zshrc
      这里我用的是zsh如果你使用系统的终端则执行 source .bash_profile

    • bin中的全部文件复制到/usr/local/bin//usr/local/lib

        cp 换成你存放的实际路径/oclint-0.15/build/oclint-release/bin/oclint* /usr/local/bin/
        sudo cp -rp 换成你存放的实际路径/oclint-0.15/build/oclint-release/lib/* /usr/local/lib/
        cp -rp 换成你存放的实际路径/oclint-0.15/build/oclint-release/include/* /usr/local/include/
      

    OCLint 官方指导手册中最后环节是直接复制文件夹到指定路径下的
    通过homebrew安装的0.13.0版本, 我提前看了下环境, 部分是链接过去的

    • usr/local/lib/路径下可以看到oclintclang文件夹

    • 通过右键菜单选中显示原身, 会跳转到实际路径是/usr/local/Cellar/oclint/0.13

    我第一次升级OCLint 0.15.0失败, 很有可能是这三个步骤中的文件夹名称, /*某一步的时候缺少了或是错了, 也可能是没有终端科学上网, 在编译期间下载某些组件时出错, 所以这里需要注意一下

  5. 验证OCLint安装成功, 执行$ oclint --version会显示:

     OCLint (http://oclint.org/):
     OCLint version 0.15.
     Built Sep  2 2020 (12:16:58).
    

    OCLint 0.13.0下还会输出LLVM 5.0.0等信息, 这里是正常的, 在OCLint 0.15.0中已经升级到了9.0.0

验证问题解决

升级OCLin 0.15.0成功后, 本地终端和jenkins分别成功完成了OCLint代码分析, 最终确认问题得到解决.

OCLint官方资料