• 5932阅读
  • 8回复

[讨论]有谁用MinGW 4.9.2编译过Debug版本的Qt 5.4.1吗? [复制链接]

上一主题 下一主题
离线johnyork
 

只看楼主 倒序阅读 楼主  发表于: 2015-03-05
我在编译Debug版Qt时总是报告错误
  1. D:\myprojects\qt-src\qt-src-5.4.1\qtbase\src\network/access/qhttpnetworkreply.cpp:67: undefined reference to `z_inflateEnd'
  2. ./.obj/debug/qhttpnetworkreply.o: In function `ZN24QHttpNetworkReplyPrivate25clearHttpLayerInformationEv':
  3. D:\myprojects\qt-src\qt-src-5.4.1\qtbase\src\network/access/qhttpnetworkreply.cpp:329: undefined reference to `z_inflateEnd'
  4. ./.obj/debug/qhttpnetworkreply.o: In function `ZN24QHttpNetworkReplyPrivate23initializeInflateStreamEv':
  5. D:\myprojects\qt-src\qt-src-5.4.1\qtbase\src\network/access/qhttpnetworkreply.cpp:716: undefined reference to `z_inflateInit2_'
  6. ./.obj/debug/qhttpnetworkreply.o: In function `ZN24QHttpNetworkReplyPrivate18uncompressBodyDataEP15QByteDataBufferS1_':
  7. D:\myprojects\qt-src\qt-src-5.4.1\qtbase\src\network/access/qhttpnetworkreply.cpp:745: undefined reference to `z_inflate'
  8. D:\myprojects\qt-src\qt-src-5.4.1\qtbase\src\network/access/qhttpnetworkreply.cpp:749: undefined reference to `z_inflateEnd'
  9. D:\myprojects\qt-src\qt-src-5.4.1\qtbase\src\network/access/qhttpnetworkreply.cpp:756: undefined reference to `z_inflateInit2_'
  10. collect2.exe: error: ld returned 1 exit status
注1:我使用MSYS2下载的MinGW-w64 32 bit 4.9.2版编译器编译的,configure选项是:
  1. ./configure -platform win32-g++ -shared -debug -opensource -confirm-license -c++11 -iconv -plugin-sql-sqlite -qt-zlib -qt-libpng -qt-libjpeg -make tools -nomake examples -no-compile-examples -prefix C:/Qt/Qt5.4.1/5.4/mingw492_32
注2:同样的编译器编译Release版的Qt似乎没有问题
离线johnyork

只看该作者 1楼 发表于: 2015-03-05
好吧,貌似是我装的Perl不是Active Perl的缘故,现在换成官方推荐的Active Perl再试试。
离线johnyork

只看该作者 2楼 发表于: 2015-03-05
换了,编译还是一样的错误,怎么回事呢?
离线johnyork

只看该作者 3楼 发表于: 2015-03-05
configure选项中 -shared换成-static就好了,为什么?
离线johnyork

只看该作者 4楼 发表于: 2015-03-05
MinGW中安了icu也不行,同样的地方报告同样的错误。有谁知道为什么吗?
离线彩阳

只看该作者 5楼 发表于: 2015-03-05
不要c++11看看?-iconv 也不要看看?
上海Qt开发联盟,热忱地欢迎你的加入!
离线johnyork

只看该作者 6楼 发表于: 2015-03-06
回 彩阳 的帖子
彩阳:
不要c++11看看?-iconv 也不要看看?

花了2天时间跟踪错误,发现是LibQt5Core.a中未输出zlib模块的API造成的。进一步分析发现<qt-src--dir>/qtbase/src/3rdparty/zlib/zconf.h中的宏ZEXPORT按预处理环境最后被定义为extern,而不是dll输出用的extern __declspec(dllexport)。
为了让ZEXPORT成为extern __declspec(dllexport),需要预定义一个宏ZLIB_DLL,而为了让编译过程能单独对-shared选项生成ZLIB_DLL宏,我更改了<qt-src--dir>/qtbase/src/3rdparty、zlib_dependency.pri:
原代码:
  1. # zlib dependency satisfied by bundled 3rd party zlib or system zlib
  2. contains(QT_CONFIG, system-zlib) {
  3.     if(unix|mingw):LIBS_PRIVATE += -lz
  4.     else {
  5.         isEmpty(ZLIB_LIBS): LIBS += zdll.lib
  6.         else: LIBS += $$ZLIB_LIBS
  7.     }
  8. } else {
  9.     INCLUDEPATH +=  $$PWD/
  10. }
更改后代码:
  1. # zlib dependency satisfied by bundled 3rd party zlib or system zlib
  2. contains(QT_CONFIG, system-zlib) {
  3.     if(unix|mingw):LIBS_PRIVATE += -lz
  4.     else {
  5.         isEmpty(ZLIB_LIBS): LIBS += zdll.lib
  6.         else: LIBS += $$ZLIB_LIBS
  7.     }
  8. } else {
  9.     INCLUDEPATH +=  $$PWD/
  10.     contains(QT_CONFIG, shared) {
  11.         DEFINES += ZLIB_DLL
  12.     }
  13. }
但是DEFINES += ZLIB_DLL似乎不起作用,在zconf.h中仍然检测不到ZLIB_DLL宏的存在。该怎么做呢?
离线johnyork

只看该作者 7楼 发表于: 2015-03-07
又折腾了一天,貌似目前无解。

configure使用-shared、-qt-zlib参数,编译出的LibQt5Core.a没有zlib的API函数,因此在编译QtNetwork.dll时无法找到使用使用的zlib API函数,编译无法通过。

configure使用-shared,不带-qt-zlib参数时QtNetwork.dll可以编译成功,但是在编译opengl时又出错了,貌似问题多多啊!
离线johnyork

只看该作者 8楼 发表于: 2015-03-11
基本搞清楚原因了:
当带-shared参数做configure时,生成的<qt-src-dir>/qtbase/src/corelib/qglobal.h会多一个宏定义“Q_VISIBILITY_AVAILABLE”,而在zlib的诸多.c文件中,该宏的存在导致ZEXPORT宏被定义为__attribute__(visibility("default")),经过MinGW编译链接后生成的Qt5Core.dll的lib文件不包含zlib API的重定向信息,因此在编译链接后续需要引用zlib模块API的dll时便出错了(我是在编译QtNetwork.dll时出错)。
暂时的解决办法:
在configure时把-no-reduce-export和-shared配合使用
进一步的思考:
经过实验,发现官网下载的Qt安装包中的MinGW4.9.1 32bit也会产生同样的错误,这说明编译器版本不兼容的可能性很小,于是造成错误的可能只有3个:1.__attribute__(visibility("default"))这个指令不适用于Windows平台;2.MinGW在实现__attribute__(visibility("default"))指令时存在Bug;3.Qt源码的配置脚本configure未充分考虑__attribute__(visibility("default"))和Windows平台的兼容性。最终哪一个才是真正的原因,还有待Qt开发组和各位高人来定位和解决。
注:因为手机打字,没在电脑旁,看不了源代码,文中的__attribute__(visibility("default"))和Q_VISIBILITY_AVAILABLE可能有误,一切以官方源码为准。
快速回复
限100 字节
 
上一个 下一个