QMake:GCC升级后系统与项目头文件冲突致Qt项目编译失败
GCC 6升级至8后Qt项目编译失败问题解析
问题背景
将GCC从6版本升级至8版本后,某Qt项目编译失败,报错信息如下:
In file included from /usr/include/qt4/QtCore/qstring.h:46, from /usr/include/qt4/QtCore/QString:1, from ../common/strings.h:11, from /usr/include/string.h:431, from /usr/include/qt4/QtCore/qlist.h:60, from /usr/include/qt4/QtCore/qhash.h:48, from /usr/include/qt4/QtCore/qdebug.h:46, from /usr/include/qt4/QtCore/QtDebug:1, from src/main.h:26, from ../common/main.cpp:9: /usr/include/qt4/QtCore/qbytearray.h:531:13: note: previous declaration ‘bool operator==(const char*, const QByteArray&)’ inline bool operator==(const char *a1, const QByteArray &a2)
经排查,问题源于系统头文件/usr/include/string.h引入了项目中的遗留头文件../common/strings.h。项目.pro文件中的INCLUDEPATH配置未发生变更:
INCLUDEPATH += . \ ../common
两种GCC版本下,/usr/include/string.h均包含#include <strings.h>语句,为何旧版GCC未触发该问题?
问题原因
核心差异在于GCC 6和GCC 8对头文件搜索优先级的处理逻辑变化:
- GCC 6及更早版本中,当系统头文件(如
/usr/include/string.h)使用#include <strings.h>形式引用时,会优先搜索系统标准库路径下的头文件,不会优先查找项目INCLUDEPATH配置的路径。旧版GCC会直接加载系统自带的strings.h,完全不会触及项目目录下的同名文件。 - GCC 8调整了这一搜索规则:系统头文件中通过
<xxx.h>形式引用的头文件,会先检查项目INCLUDEPATH配置的路径,再去系统标准路径查找。这就导致系统string.h引用<strings.h>时,先找到了项目../common目录下的strings.h,而该文件又引入了Qt头文件,最终引发了重复声明的编译冲突。
本质上是GCC 8提升了项目INCLUDEPATH在系统头文件引用时的搜索优先级,才暴露了之前隐藏的同名头文件冲突问题。
内容的提问来源于stack exchange,提问作者Swift - Friday Pie
相关产品推荐
相关产品推荐

