高通QSSI方式导致CI编译失败问题记录

一、问题背景
1、QSSI说明
QSSI 是 Qualcomm Single System Image 的缩写,高通平台从Android Q开始,为了解决Android碎片化问题,把system.img和vendor.img进一步拆分,增加了QSSI编译选项,QSSI就是用来编译system.img的。

2、有QSSI和没有QSSI的编译流程对比
没有QSSI时:

 source build/envsetup.sh
 lunch target
 make

有QSSI时:

#编译system.img
$ source build/envsetup.sh
$ lunch qssi
$ make
#编译其他img
$ source build/envsetup.sh
$ lunch target
$ make

3、编译方式的变化
增加了QSSI的编译选项,高通平台的编译模式也对应发生了变化,从传统的make编译脚本变为使用build.sh文件进行编译。
从只编译一个target选项,到现在需要分别编译QSSI和target两个部分。

二、问题介绍
1、问题现象
jenkins搭建CI,new build可以编译成功,但是remake一直编译失败,查看编译脚本,对比了new和remake的区别,

参考图示,可以发现,new编译前会做make clean的动作,清理编译产物,但是remake时只进行了更新编译,之前的编译产物还是存在的。

编译方式的不同,导致了不同的编译结果。
高通QSSI方式导致CI编译失败问题记录_第1张图片
2、log分析
1)分析报错log,log显示如下:
高通QSSI方式导致CI编译失败问题记录_第2张图片
报错提示找不到qssi-target_files-xxx.zip压缩包。但是按照报错提示路径去找压缩包时,可以看到对应压缩包文件是存在的,而且压缩包不止一个,同目录下同时存在多个带有数字后缀的压缩包,所有就有两个疑问:
a、为什么会产生这么多带有数字编号的压缩包?
b、已经存在对应的压缩包了,为什么还会因为找不到压缩包而报错?

2)带着上述疑问,同步使用另外一台机器编译,发现如下:
高通QSSI方式导致CI编译失败问题记录_第3张图片
同样remake,本地可以编译成功,但是jenkins CI编译fail,并且CI报错的文件压缩包名,跟本地生成的包名有差异?

3)分析代码
首先查找qssi*-target_files-*.zip压缩包文件名的由来,在build/make/core/version_defaults.mk文件中
高通QSSI方式导致CI编译失败问题记录_第4张图片
可以看到文件名字tag是通过匹配HAS_BUILD_NUMBER宏来决定的,匹配成功文件名tag即带有数字编号,匹配不成功,文件名tag就是编译机器的用户名,本地机器环境中没有BUILD_NUMBER宏,所有生成的压缩包名固定不变,但jenkins环境存在BUILD_NUMBER编译宏,所以生成的压缩包名跟随jenkins编译序号变化。再叠加remake操作,编译产物没有被清理,就会导致编译生成的文件目录里有一系列带编译序号的压缩包存在。

4)既然压缩包存在,为什么会匹配失败呢?
在编译脚本build.sh文件中,OTA生成函数中会将需要check的压缩包查找出来,这个查找使用的是"find"模糊匹配,Jenkins编译时就会匹配出多个文件包,并且会将匹配出来的多个包当成一个文件名,在进行校验的时候,就会因为包名不一致校验失败,导致编译报错。
高通QSSI方式导致CI编译失败问题记录_第5张图片以上描述可以理解成:
高通QSSI方式导致CI编译失败问题记录_第6张图片
BUILD_NUMBER是jenkins的特定宏,高通的编译脚本里也应用了这个宏,所以CI remake的时候匹配成功了,编译生成产物就会带有数字编号,如qssi-target-files-1907.zip等,再加上remake编译,不清理编译产物,就会导致编译目录里存在多个带有数字编号的压缩包,find模糊查找到多个压缩包,并把它们当成一个文件,导致校验fail编译失败了。

三、解决方案
CI执行编译前,主动在CI jenkins job中将相关报错文件删除,保证编译目录下只存在一个压缩包。
高通QSSI方式导致CI编译失败问题记录_第7张图片
四、经验共享
高通有QSSI编译选项的平台,在CI搭建过程中,都存在这个问题,所以解决方案同样适用,目前此方案已应用到后续高通项目。

你可能感兴趣的:(ci/cd,jenkins,android)