使用Qt Creator / qmake / MinGW在调试构建中PRECOMPILED HEADERS无法工作。

4
在Qt Creator中,我有一个使用预编译头文件的pro文件。
在发布模式下构建时,构建工作非常完美。但在调试模式下构建会出现错误,生成对象文件失败。例如:
17:12:40: Running steps for project Euclide...
17:12:40: Configuration unchanged, skipping qmake step.
17:12:40: Starting: "C:\Qt\Tools\mingw48_32\bin\mingw32-make.exe" 
C:\Qt\5.2.0\mingw48_32\bin\qmake.exe -spec win32-g++ CONFIG+=debug -o Makefile ..\euclide\Euclide.pro
C:/Qt/Tools/mingw48_32/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'C:/UserPrograms/Euclide/build'
g++ -c -include debug\_pch.h -pipe -fno-keep-inline-dllexport -std=gnu++11 -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_WEBKITWIDGETS_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_QUICK_LIB -DQT_POSITIONING_LIB -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_WEBKIT_LIB -DQT_MULTIMEDIA_LIB -DQT_QML_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DQT_SENSORS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\euclide -I"..\..\..\Program Files (x86)\boost\boost_1_53_0" -I"..\numlib\mathvec" -I"..\..\..\Qt\5.2.0\mingw48_32\include" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtWebKitWidgets" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtMultimediaWidgets" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtQuick" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtPositioning" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtOpenGL" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtPrintSupport" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtWebKit" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtMultimedia" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtQml" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtWidgets" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtNetwork" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtSensors" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtGui" -I"..\..\..\Qt\5.2.0\mingw48_32\include\QtCore" -I"debug" -I"." -I"." -I"..\..\..\Qt\5.2.0\mingw48_32\mkspecs\win32-g++" -o debug\main.o ..\euclide\main.cpp

Makefile.Debug:1543: recipe for target 'debug/main.o' failed
mingw32-make[1]: *** [debug/main.o] Error 1
mingw32-make[1]: Leaving directory 'C:/UserPrograms/Euclide/build'
makefile:34: recipe for target 'debug' failed
mingw32-make: *** [debug] Error 2
17:12:59: The process "C:\Qt\Tools\mingw48_32\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project Euclide (kit: Desktop Qt 5.2.0 MinGW 32bit)
When executing step 'Make'
17:12:59: Elapsed time: 00:19.

真正令人困惑的是,它在发布模式下运行良好。我做了一些小项目的测试,在发布模式或调试模式下都能正常运行,但由于某种原因,一个较大的项目失败了。甚至无法在调试模式下编译项目中的单个文件。 以下是pro文件:

QT += core gui \
    webkitwidgets \
    printsupport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Euclide
TEMPLATE = app

QMAKE_CXXFLAGS += -std=gnu++11

CONFIG += precompile_header

# Use Precompiled headers (PCH)
PRECOMPILED_HEADER  = _pch.h    

SOURCES +=  main.cpp\
    mainwindow.cpp \
    zero.cpp \
    ... lot of files here...
    debug_tool.cpp

HEADERS += mainwindow.h \
    zero.h \
    ... lot of files here...
    debug_tool.h \
    _pch.h

FORMS += mainwindow.ui \
    zero.ui \
    ... other files...
    apphelp.ui \
    message.ui

INCLUDEPATH = "C:/Program Files (x86)/boost/boost_1_53_0"

LIBS += \
    ../build/release/exprcompiler.dll

RESOURCES += \
    resources/euclide_resources.qrc

我在网上进行了几天的广泛研究,以解决这个问题,但是并没有找到任何解释,即使有关qmake的文档非常完整...

有人知道如何解决这个问题吗?因为我现在考虑的唯一解决方案是,在没有预编译头文件的情况下,拥有一个特殊的“Debug”版本的所有项目... 感谢您的帮助。


请问您能否提供一个自包含的示例以重现此问题?请参考 sscce.org 了解详情。 - László Papp
1
@Laszlo:这个项目现在已经很大了,有几十个文件(不包括头文件和动态链接库源代码),所以很遗憾我不能发布代码。但是编译输出除了我帖子顶部的debug/main.o error 1之外没有任何解释。此外,小型项目在两种模式下都可以正常工作,我不知道该去哪里找到问题。 - Hugo
@Hugo:如果您无法提供自包含的代码,我不确定您希望得到怎样的帮助。我建议在提供最小测试案例之前先关闭此问题。 - László Papp
问题不在于代码(程序行),它可以快速编译并在发布模式下正常工作。问题来自Edi,或编译链,或其他与代码无关的原因。在某个时刻,我曾考虑过pro文件,但显然不是这个问题。也许PCH数据库因为某种原因在调试中被耗尽/损坏了;我不知道。任何单个文件都无法在调试中逐个编译。 - Hugo
1
@LaszloPapp 我个人认为这是一个可以接受的问题。问题不是“我的项目中有什么错误”,而是“PCH可能会导致什么问题出现”的一般性问题。如果它没有一个有意义的答案(即,答案是“你的代码有错误”),那就没关系了,它不会得到一个好的答案,并且可能成为自我关闭的候选人。另一方面,如果预编译头文件确实存在特定问题需要解决,这可能对未来的其他人有所帮助,并且是一个合理的问题。 - Joe
显示剩余16条评论
1个回答

6
我(可能)遇到了同样的问题,并花了一些时间找出了问题所在。
经过一些尝试,创建一个MWE,我发现.pch文件的大小似乎对这个问题至关重要。
使用大于128MB的PCH会中止编译而没有任何消息,并返回代码1(而不是成功编译的0)。
我的研究类似于这篇GCC邮件列表条目中所述的问题。
似乎唯一的解决方法是将PCH文件的大小减小到128MB以下
仅供记录: 我正在使用Qt 5.2.1中包含的MinGW(rev2)gcc 4.8.0 32位在WinXP 32位和Win 8 64位上使用QMake项目。
另一方面,我的GCC 4.8.2 64位在Linux下吃掉了一个约5GB的PCH文件而没有投诉(我本来想测试一个更大的文件,但是编译这个文件几乎超出了我的RAM)。

深入挖掘

我生成了一个头文件作为PCH使用,其内容如下:
class _1 {};
class _2 {};
class _3 {};
class _4 {};
class _5 {};
class _6 {};
class _7 {};
class _8 {};
class _9 {};
class _10 {};
//...

使用二分查找(用于此文件中的类数),我发现将此文件填充为128273个类会生成一个大小为135266564字节的PCH文件,并且可以在编译其他文件时使用。使用128274个类生成的PCH文件的大小为135270660字节,并且使用此PCH进行编译会失败。
我不确定如何处理这些信息。不提供错误消息肯定是错误的,但我不知道谁应该受到责备(GCC(版本?),MinGW / Windows,32位性)。也许有更多时间的人可以决定并通知正确的人?

太好了!我遇到了与Qt 5.3.0(使用gcc 4.8.2)相同的问题。将QtCore、QtGui和QtWidgets包含在pch中(这大大减少了编译时间)产生了136MB,并且在pch之外的第一个编译文件上构建失败。只包括QtCore和QtGui则产生了119MB,构建成功。 - Xilexio
2023年了,这个问题仍然没有解决... Qt 5.15.4和mingw32-g++ 11.3.0。 - supernun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接