在嵌入式的C和C++项目里面,QAC报头文件找不到这种事,是挺常见的,它说找不到,往往倒不是代码里面真的就少了那么一个文件,而是在QAC的项目里头,没有拿到跟真实编译时候一模一样的那些包含路径、宏的定义、编译器的选项,还有工程的根目录,按照Perforce Helix QAC的文档说明,项目的文件,是需要从真实的构建环境里面,去把它相关的那些选项给提取出来的;而构建监控这个功能,也会在构建的过程当中,去把那些被编译的文件、它们的路径,还有其它的信息,全给识别下来。
一、头文件缺失了要怎么处理
QAC在报头文件缺失的时候,你可不能只是在那个报错的文件里面,把包含路径给硬生生地改成一个绝对路径,这么做,看着好像是能把眼前这个错误给绕过去了,可是到了后面,它会接着给你引出来一堆,像宏定义、条件编译,还有那种拐着弯被引用的头文件,这一类的问题,一种更稳当的做法,是要让QAC的项目,和编译器它们俩,看到的是同样一套工程的信息。
1、要先去确认一下,真实的编译是不是能顺利通过
先在你原来用的那个IDE、Makefile、CMake,或者是持续集成的环境里面,去完整地编译一次看看,要是连真实编译那一步,都说缺了头文件,那你就得先去把工程本身的问题给修好;可要是真实的编译是正常的,就QAC在那一个劲儿地报错,那就要集中精力去查QAC同步的配置,千万不要一边工程那边根本编不过,一边还在QAC里面,去手动地补那些路径,最后补来补去,只会越补越乱。
2、用构建同步的办法,去把路径给导进来
可以通过QAC的同步功能,从构建的环境里面,去把源文件、宏的定义,还有包含的路径,给一块儿提出来,按照Perforce的文档说明,命令行的同步工具,是可以从用户自己的构建系统,或者是环境里面,去把文件自动地同步到QAC的项目里头去的,等同步完了以后,再接着往下做分析和出报告,要是你的项目,是用CMake、Makefile,或者是IDE来管的,那就优先去用构建监控,或者是同步的办法,去把项目给生成出来,尽量少去靠手工,一样一样地往里头添加。
3、去把工程的根目录给补齐了
要是源码、平台相关的代码,还有第三方的库,它们是分散在好几个不同的目录里面的,那你就需要在QAC里头,去配置好合适的项目根目录,官方的文档里是这么说的,Helix QAC它是支持去设置好几个源文件的根目录的,在碰到第三方代码这一类场景的时候,可能是需要一个以上的根目录才够用的,要是根目录给弄错了,那在界面里面,你看着那些文件好像是好端端地待在那里,可实际到了去解析包含关系的时候,QAC还是有可能找不到它们。
4、去检查一下预编译的头文件
在C++的项目里面,要是用到了预编译的头文件,那QAC这边,也得把对应的配置给拿到手,按照Perforce关于Visual Studio同步的说明,同步的内容里头,是包括了项目和系统的包含路径、预编译的头文件,还有在指定的那个配置底下,参与了构建的那些文件的,要是像那种标准的预编译头文件,或者是工程里面统一引用的头文件,没有被识别出来,那到了后面,就会稀里哗啦地,出现一大片连带的缺失报错。
二、头文件路径配置错误了要怎么排查
QAC的头文件路径配置出错了,这种错误,常常是会集中地冒出来,在路径的层级、路径的先后顺序、系统头文件、条件编译,还有大小写这几点上头的,在动手排查的时候,是要拿着真实跑过的编译命令,去跟QAC的配置,放在一起对照着看的,而不是只盯着报错提示里面,说缺了哪一个.h文件。
1、去核对一下包含路径的那些参数
要先去看一看,在真实的编译命令里面,那些用来指定包含路径的参数,都是怎么写的,然后再拿着它们,去跟QAC项目的配置,一个一个地对,按照Perforce的文档说明,包含路径的那个选项,它就是用来告诉编译器,包含路径的标志是个什么样子的,在Linux底下,默认常用的是一种,到了Windows底下,默认又成了另一种,而GCC呢,它可能还会用到别的格式,要是你的项目,用到了什么特别的编译器参数,那在QAC里面,也得把它给补进去。
2、去检查一下路径的层级,是不是多写了一层,或者是少写了一层
就比如说,代码里面写的是去包含一个在某层子目录下的头文件,那你的包含路径,就应该是指向它的上一级目录的;可要是代码里,直接就写了那个头文件的名字,那包含路径,才应该是老老实实地指向它所在的那个目录,有好多的报错,其实就是在这个地方,给搞错了一层,文件它是确确实实待在那里的,只是搜索的路径,跟它怎么都对不上罢了。
3、去检查一下宏的定义,它是不是影响到了,最后到底选了哪一个头文件
在同一个工程里面,是有可能会靠宏的定义,去选择不同芯片的平台、不同实时操作系统的版本、还有不同编译器的适配头文件的,在真实的编译命令里面,是带着那些用来定义宏的参数的,一旦QAC这边,把这些参数给漏掉了,那它就很可能会,一头扎进另外一条包含的分支里面去,然后紧接着,就开始报头文件缺失了。
4、去检查一下大小写,还有那种相对路径的写法
在Windows的那个环境里面,它对大小写是不怎么敏感的,可是到了Linux的构建机上,还有一部分持续集成的环境里面,就会变得很敏感,头文件它真实的文件名,可能带着大写字母,可你在代码里面,却全给写成了小写的,这在本地可能啥事都没有,可一换到QAC待着的那个环境里,它就立马开始报错了,还有就是在相对路径里面,那种往上一层、再往上一层,用得太多的情况,也是很容易在工程被挪了个地方以后,就失效了的。
三、头文件缺失要怎么样才能避免它反反复复地出现
在把头文件缺失的问题,修好了一次以后,还得去把处理它的那套规则,给固化下来,要不然的话,等到换了一台机器、切到了另一个分支、或者是换了一套构建的配置,QAC那边,很快就又会报出来一模一样的问题。
1、去把同步的来源给固定下来
团队里面,应该去约定好,QAC的项目,到底是从哪一个构建的配置上同步过来的,就比如说,是调试版的、发布版的、专门给安全用的,还是准备拿去量产的,因为不同的配置底下,宏的定义,还有包含的路径,它是有可能不一样的,要是把它们给混着用了,是会让分析出来的结果,变得不再可靠的。
2、去把那些路径,给写到构建的系统里面去
那些能被写进CMake、Makefile,还有工程文件里面的路径,就不要只留在QAC的界面上,临时去补那么一下了,这么做,真实的编译,和QAC的分析,这俩就能去共用同样一套来源,到了后面,维护起来的成本,也会稍微低上那么一些。
3、去把分析的日志给留下来
每一次跑QAC分析的时候,都要去把同步的日志、编译的命令、规则的配置,还有项目的版本,这些东西给留存下来,这样,等后面再冒出来头文件缺失的问题时,就可以直接去拿这一次的记录,跟上一次正常分析时候的包含路径和宏定义,去对比一下它们之间的差异,定位起来,是会快上很多的。
总结
关于QAC要怎么去处理头文件缺失,还有头文件的路径配置出了错,又要怎么去排查,这里面的关键,就是得让QAC,能看到真实的编译环境,在做处理的时候,要先去确认一下,原来的工程是能编得过的,然后再用构建同步的方式,去把文件、路径、宏的定义,还有预编译的头文件,都给导进来;到了排查的时候,就要拿着真实的编译命令去做对照,重点去看包含路径的参数、路径的层级、宏的定义,还有大小写,等到全都处理完了以后,还要去把路径和配置,都给固化到构建的系统里面去,这样才能避免,每一次都靠着手工,去临时地补救它。