mingw qt(能夠去掉mingwm10.dll、libgcc_s_dw2-1.dll、libstdc++-6.dll的依賴,mingw默認都是動態連接gcc的庫而TDM是靜態連接gcc庫,t...

原文地址: mingw qt 做者: 孫1東

不使用Qt SDK,使用mingw編譯qt源代碼所遇問題及解決方法:html

configure -fast -release -no-exceptions -no-rtti -no-stl -no-qt3support -no-opengl -no-multimedia -no-webkit -no-script -no-scripttools -nomake tools -nomake examples -nomake demos -nomake docs -nomake translations -platform win32-g++java

強烈推薦使用tdm版本的mingw gcc,相比官方mingw的慢速,晦澀,tdm的安裝過程簡單,清晰,更新也快,並且官方的mingw開發人員也在使用tdm(爲啥不合並了算了呢)。

【關於mingw10.dll,libgcc_s_dw2-1.dll,libstdc++-6.dll】c++

mingwm10.dll 是線程安全的異常處理時用到的清理函數,不然將會有內存泄漏。web

libgcc_s_dw2-1.dll 是gcc 的核心運行庫。express

libstdc++-6.dll 是gcc支持的特定語言c++的運行庫。windows

用mingwrt3.18以前編譯出來的qt庫,默認依賴mingwm10.dll。使用mingwrt3.18編譯qt庫再也不依賴mingwm10.dll編譯出來的qt庫不能用upx進行壓縮,這個確認是upx的bug,由於使用aspack是沒有問題的。若是想在3.18之前去掉依賴,因爲qt自己不使用異常處理,因此能夠在configure的時候,選項 -no-exceptions 禁止異常處理從而去掉對mingwm10.dll的依賴,而且這樣編譯出來的qt庫體積還縮小很多。
用官方gcc4.4.0編譯出來的qt庫,默認依賴libgcc_s_dw2-1.dll,gcc-4.5.0默認還多一個依賴libstdc++-6.dll。官方的mingw默認都是動態連接gcc的庫而TDM是靜態連接gcc庫。使用官方mingw要想去掉對gcc核心庫libgcc_s_dw2-1.dll依賴的話,能夠在編譯qt庫以前修改QTDIR/mkspec/win32-g++/qmake.conf,QMAKE_LFLAGS = -static-libgcc。或者configure以後修改QTDIR/.qmake.cache,QMAKE_LFLAGS += -static-libgcc。取消對c++運行庫libstdc++-6.dll的依賴,使用選項-static-libstdc++。修改QTDIR/.qmake.cache順便還能夠選擇不編譯examples,demos等等部件,只保留libs。或者configure的時候指定 -nomake tools -nomake examples -nomake demos -nomake docs -nomake translations安全

相對官方mingw的繁雜,使用tdm版的mingw的好處不少,首先,安裝過程簡單清楚,其次產生的qt庫不依賴libgcc_s_dw2-1.dll,libstdc++-6.dll,而且若是用tdm-gcc-4.5.0(mingw-runtim-3.18)的話,連mingwm10.dll也不須要了。tdm有兩個版本,sjlj和dw2,這是兩種不一樣的異常處理方式,sjlj是老的方式,速度慢,可能更穩定些;dw2是新的方式,速度更快。tdm4.5.0默認是用sjlj的,固然也提供了dw2的版本。除了下載官網上給出的dw2版本的文件,可能須要再下個libexpat-2.0.1-1-mingw32-dll-1.tar.gz,(不知道缺了會怎樣),由於我試了用on-demand安裝的時候,選dw2,他是會安裝libexpat.dll的。而後把全部帶-dw2的重命名爲不帶dw2的,好比g++-dw2從新命名爲g++,tdm的說明裏說這兩個版本能夠和平共處,後面有如何作到。app

【使用gcc 4.4.0編譯出現亂碼】函數

gcc4.4會自動檢測當前的locale,併產生相應的輸出。如要使用純英文環境,設置一下環境變量 LANG=C 或者 LANG=en_US。工具

【有時候編譯QT會出錯誤:qtvariantproperty.cpp:1927: internal compiler error】

具體緣由未知,有人說是gcc的bug,我懷疑跟內存使用狀況有關。因此最好是編譯過程當中不要搞別的動做,這樣會大大減小出現這種狀況的概率。不過既然有時候仍是會出現這樣的問題也得有個解決辦法,通過研究能夠這樣:先去QTDIR/tools/designer/src/lib下,刪除tmp目錄以及全部qmake生成的makefile,手動qmake,生成makefile,此時先別make,雖然這時能夠成功,但後面的編譯沒法繼續,因此要先回到QTDIR目錄,再make。

【使用gcc4.5.0編譯qt4.6.2,報錯0xc00000005】

按照gcc4.5.0的說明也不能解決,其實qt的conf文件裏面已經添加有這樣選項。

使用tdm-gcc-4.5.0(sjlj或者dw2都可)。

【默認編譯QT時不編譯phonon模塊】

mingw須要打上相應的補丁 補丁中全部文件放到mingw/include下,爲了使用補丁還須要下載MSYS 和patch,patch用法:patch < dshow.patch,這樣就打好補丁了。這樣在configure qt時,就會自動檢測到系統支持phonon,因而phono庫將被編譯。單獨安裝的MSYS(core)使用某些命令時會出現warning:terminal is not fully functional (press RETURN),這是因爲沒有設置/etc/termcap,使用MSYS完整安裝版把它下面的termcap考過來就能夠了,或者乾脆就用完整安裝的MSYS算了,就是版本稍老一點而已,那裏面基本上什麼都有了。

【編譯dbus】

dbus跟phonon同樣,也是須要額外支持才能編譯,首先下載windbus,地址 src/dbus make

【安裝qt以後,改變qt的位置】

 

qt編譯完了目錄不能隨便更名,不然會出現某文件找不到的情形,qt編譯時把當前qt的路徑硬編碼到qt庫中以及qmake中,等等,因此不能隨便更名。若是要更名能夠:

1.使用qpatch,這個是qtcreator帶的小工具,當安裝qt sdk的時候,安裝程序就是經過運行qpatch來更改qt安裝目錄的。使用方法:qpatch files-to-patch-windows oldQtDir newQtDir。假設原來的安裝目錄是C:Qt2010.04,更名後的目錄爲C:Qt2000.00。運行命令行,進入C:Qt2000.00bin目錄,qpatch files-to-patch-windows C:/Qt/2010.04/qt c:/qt/2000.00/qt,files-to-patch-windows指定的替換文件列表都是位於qt目錄下的,也就是prefix=C:/Qt/2010.04/qt,qpatch 會根據c:/qt/2000.00/qt+files-to-patch-windows找出全部須要替換的文件。這裏須要注意大小寫,奶奶的,看來Qt的工程師也有很多缺心眼的,windows下比較目錄字符串竟然是大小寫敏感的,害的我琢磨了半天,明明看着有這個路徑竟然替換不了,好在老夫靈光一閃,嗯。。我真聰明。使用qpatch有個限制就是更名後的目錄長度不能大於原來的長度,這也就是爲何安裝包裏未解壓出來的默認目錄是一大長串的緣由。

2.還有一種方法可使用qt.conf:,在qt/bin下建立文件qt.conf,其內容以下:

[Paths]
Prefix = C:/xxx/yyy

老外說prefix指向的目錄必須包含.LICENSE-EVALUATION這個文件,固然通常都是這樣。

這樣能夠從一個地方build出多個qt的版本放到不一樣的位置,編譯好後,不須要的目錄能夠刪除,保留bin,lib,plugins,tools,include,src,mkspecs.這樣qtcreator就能正確識別qt不一樣版本.

【qtcreator中按F1獲取上下文幫助,顯示No documentation available】

尤爲裝了多個版本的qt,很容易形成這種混亂,

xp系統下,刪除C:Documents and SettingsAdministratorApplication DataNokia。

win7系統下,刪除C:UsersdarkAppDataRoamingNokia

再從新啓動qtcreator便可。

【qtcreator1.3.1->Tools->Options->Qt versions->Debugging Helper顯示紅叉叉】

先rebuild,一切正常的話,將在QTDIR/qtc-debugging-helper目錄下生成gdbmacros.dll,這樣就變綠勾勾了。不過雖然能夠找到helper庫,可是在調試程序的時候仍是不能正確顯示Qt類以及stl,提示debugging helpers not found,金山打字通2010免費下載。後經反覆驗證,發現緣由是gdb版本不匹配,我本身安裝的mingw用的是gdb7.1而debugging helper只能支持到gdb6.8。解決方法爲使用qtcreator自帶的mingw中的gdb或者本身下個gdb6.8。還有一種狀況,好像必須得在qt程序(至少qtcore)裏才行,純c++的程序也會提示debugging helpers not found。

【qt 4.6.3靜態編譯後使用出錯】

編譯的過程沒有問題,可是使用libQtGui.a的時候報錯:

undefined reference to '_imp___Z21qt_call_post_routinesv'
undefined reference to '_imp___Z21qDeleteInEventHandlerP7QObject'

這個是qt的bug,使用4.6.2沒有問題

【編譯選項雜項】

修改$QTDIRmkspecsCOMPILERqmake.conf,其中COMPILER=win32-g++或者msvc-2008

win32-g++: QMAKE_CFLAGS_RELEASE    = -Os -momit-leaf-frame-pointer
msvc-2008: QMAKE_CFLAGS_RELEASE    = -O1 -Og  -GL -MD

For anyone who is interested in a compiling fully static libraries for msvc (no msvcrtXX.dll dependence), you need change the QMAKE_CFLAGS_RELEASE from -MD to -MT, and add /NODEFAULTLIB:」MSVCRT」 to the QMAKE_LFLAGS_RELEASE.

 

tdm 的dw2版,不更名,編譯即便用:gcc-dw2,g++-dw2,cpp-dw2,mingw32-gcc-dw2等等

首先修改QTDIR/qmake/Makefile.win32-g++:

CXX        =    g++-dw2

LINKQMAKE   =    g++-dw2 $(LFLAGS) -o qmake.exe $(OBJS) $(QTOBJS) $(LIBS)

這樣,qmake就能夠正常生成了,接下來是qt庫,

再修改QTDIR/mkspecs/win32-g++/qmake.conf

QMAKE_CC        = gcc-dw2

QMAKE_CXX        = g++-dw2

QMAKE_LINK        = g++-dw2
QMAKE_LINK_C        = gcc-dw2

QMAKE_RC        = windres --preprocessor=cpp-dw2

注意最後一個windres 調用gcc,gcc又調用cpp因此,直接cpp-dw2,否則仍是找不到。

【qwt以及通常的designer插件】

qwt是一個繪製統計圖的庫,也做爲designer的插件集成到qtcreator裏,這裏須要注意的問題是

IDE與編譯器的配合:若是使用的是qtsdk自帶的qtcreator,因爲它自己是用msvc編譯的,爲了使qwt的插件能被qtcreator識別,必須使用msvc編譯qwt,產生兩個dll,一個是qwt designer的插件qwt_designer_plugin5.dll這個放在qtcreator的designer目錄下,不過此時運行qtcreator仍是不能顯示qwt的插件,由於它還依賴qwt.dll。再將qwt5.dll放到qtcreator的bin目錄下,這樣再運行qtcreator就能夠看見qwt的插件了。然而事情尚未完,當應用程序使用qwt類庫的時候,因爲qt sdk的編譯器是mingw,因此必須使用mingw從新編譯qwt的類庫,生成的designer插件就不須要了,生成的libqwt5.a放在qt/lib下或者隨便什麼地方,這個導入接口庫只是爲了編譯能成功,生成的qwt5.dll放在qt/bin下,或者直接放在可執行文件的目錄下,這是運行時真正要調用的。

明白了以上,那麼固然更好的辦法就是不用qt sdk,而是統一使用msvc編譯,因而這樣組合:下載單獨的qtcreator(默認爲msvc編譯)+qt library msvc,這樣只需編譯一次qwt便可。

下載msvc 2008 express,安裝
下載單獨的qt creator(默認使用msvc編譯),安裝
下載qt libraries (msvc版),安裝
打開qtcreator 將編譯環境指定爲使用剛剛下載安裝的qt (msvc版)
下載qwt-5.2.1源代碼,解壓
使用qtcreator打開qwt工程,編譯release版本
將qwt-build-desktopdesignerpluginsdesignerqwt_designer_plugin5.dll放到qtcreatorbindesigner目錄下
將qwt-build-desktoplibqwt5.dll放到qtcreatorbin目錄下
從新運行qtcreator你將會看到designer裏已經有qwt的控件出現,但還不能應用於程序中
爲了讓程序中能使用qwt控件,還需再作幾件事
將qwt-build-desktoplibqwt5.lib放到qtlib目錄下
將qwt-build-desktoplibqwt5.dll放到qtbin目錄下
從新運行qtcreator,新建一個工程,隨便拽個qwt控件到form上
.pro中添加:
LIBS += -lqwt5
INCLUDEPATH += qwt-5.2.1src 這裏使用你本身的路徑
如今能夠試試效果了

【LIBS vs LIBS_PRIVATE】

首先記住LIBS或者LIBS_PRIVTE,-Lpath -lname 後面都不能有空格。path中有空格的話

$$quote(-Lpath),path中可使用""或者"/"均可以,不須要轉義""。

有時候很詭異,LIBS -L"path" -l"name"不起做用,而放到默認的qt/lib下就行。

這時可考慮使用LIBS_PRIVATE,還不行就直接完整路徑。

【多核編譯】

mingw32-make 參數設置 --jobs 或者 -j x ,x 是處理器的個數+1,貌似不起做用,設置了MAKEFLAGS=-j3也不行,或許根據環境自動就-jx了?

qtcreator自動使用jom代替nmake,個人雙核,jom -j 2,果真cpu佔用達到了100%.

【meta object system】

meta object system除了實現了signal/slot,還實現了C++的擴展RTTI,相似java中的反射,運行時獲取類的全部信息。

由於qmake?不??理 .cpp中的Q_OBJECT(一般也不多有人?把Q_OBJECT?在.cpp,而是?在.h中),因此,若是.cpp中有Q_OBJECT的?,?? ?生出 undefined reference to 'vtable for xxx ????.添加#include "xxx.moc" 放到 xxx.cpp 最尾端(必定要放最後一行)

【mingw dll 與 msvc dll】

不一樣的編譯器實現dll導出名字(name mangling)是不一樣的,對函數導出,咱們可使用統一的,通過extern "C" 處理過的不帶修飾的名字從而實現互聯互通;而對類的導出則複雜得多,涉及ABI(Application Binary Interface)的問題,需另外討論。

app 調用 dll 可分爲4種狀況:

1.mingw app調用 mingw dll

固然自家人認識自家人,pro裏直接LIBS += mingw.dll就能夠,甚至不須要.a或者.lib

2.msvc app 調用 mingw dll

msvc app架子大,不認別人,直接使用mingw.a導入庫是不行的,至少release app不行,debug app倒還湊合能跑,緣由未知。正確的方法爲使用msvc的工具 生成msvc app須要的lib接口. 爲了生成lib接口,咱們須要有個def文件,這個能夠在編譯mingw dll時自動生成,加入連接選項:QMAKE_LFLAGS += -Wl,--output-def,xxx.def.有了def 接下來的事情就簡單得很了。執行:lib /machine:i386 /def:xxx.def.這樣就生成了msvc app所需的xxx.lib和一個沒用的xxx.exp.

而後再pro裏LIBS += xxx.lib就好了

3.mingw app 調用 msvc dll

同 1. 直接LIBS += msvc.dll

Usually (read: for all DLLs created with MinGW and also a few others) MinGW links fine against a DLL.  No import library is necessary .

4. msvc app 調用 msvc dll

沒啥說的

【使用QtTest】

QT += testlib 或者 CONFIG += qtestlib

http://blog.sina.com.cn/s/blog_930982070101edqf.html
相關文章
相關標籤/搜索