增量构建C/C++混合32位可执行文件时Bullseye编译报错
问题分析
这是Bullseye Coverage 9.0.7的兼容性bug,核心原因是增量构建时,covc错误地将你的编译参数(包括-include test.h)传递给了自身内部的C代码编译流程:
- 你的
test.h仅在非C++环境(!defined(__cplusplus))下包含<stdlib.h>; - 增量链接阶段,Bullseye会编译自身的
libcov-posix.c(纯C代码),但由于你使用clang++作为编译器,该编译过程会自动定义__cplusplus宏; - 此时
test.h的条件判断跳过了<stdlib.h>的包含,而program_invocation_name是GNU扩展中定义在<stdlib.h>的标识符,因此触发未声明错误。
首次构建正常是因为此时Bullseye的内部编译未受增量构建的参数继承影响,而增量构建时covc错误复用了用户的编译参数。
解决办法
方法1:修改test.h适配Bullseye编译
Bullseye编译自身代码时会定义__COVC__宏,修改test.h的条件判断,让Bullseye的内部C代码也能包含<stdlib.h>:
#ifndef hNesLibUT #define hNesLibUT // 非C++环境 或 Bullseye内部编译时,包含stdlib.h #if !defined(__cplusplus) || defined(__COVC__) #include <stdlib.h> #endif #endif
这个改动不会影响项目原有逻辑,同时能让Bullseye的内部编译正常找到program_invocation_name的声明,是最简洁的解决方案。
方法2:隔离编译与链接的参数
将-include test.h仅应用在编译源文件的阶段,链接阶段清空可能传递的参数:
main: main.o simple_math.o COVCFLAGS="" /usr/bin/ccache "/opt/BullseyeCoverage/bin/covc" /usr/bin/clang++-16 -m32 -o main main.o simple_math.o
通过临时清空COVCFLAGS,避免covc将编译阶段的参数传递给链接时的内部编译步骤。
方法3:强制暴露GNU扩展声明
如果修改test.h受限,可在编译命令中添加-D_GNU_SOURCE,强制<stdlib.h>暴露GNU扩展标识符:
simple_math.o: simple_math.c /usr/bin/ccache "/opt/BullseyeCoverage/bin/covc" /usr/bin/clang++-16 -m32 -D_GNU_SOURCE -o simple_math.o -c simple_math.c -include test.h main.o: main.cpp /usr/bin/ccache "/opt/BullseyeCoverage/bin/covc" /usr/bin/clang++-16 -m32 -D_GNU_SOURCE -o main.o -c main.cpp -include test.h
_GNU_SOURCE会让<stdlib.h>包含所有GNU扩展的声明,即使test.h未包含该头文件,Bullseye的内部代码也能找到program_invocation_name的定义。
内容的提问来源于stack exchange,提问作者Joshua Schroijen
相关产品推荐
相关产品推荐

