詳解編譯Windows平臺下靜態(tài)Qt庫
如何編譯在Windows平臺下實現(xiàn)真正意義上的靜態(tài)Qt庫是本文要介紹的內(nèi)容,在網(wǎng)上看到了這么一篇對大家有幫助的文章,與大家分享一下。
編譯Windows平臺下靜態(tài)Qt庫是本文要介紹的內(nèi)容,我在國內(nèi)外Qt論壇上看到的最多的問題之一就是如何編譯靜態(tài)Qt庫,可見在動態(tài)鏈接庫 (Windows: .dll, Linux: .so)大勢所趨的今天,靜態(tài)鏈接庫還是具有其存在的合理性和廣泛需求。首先看看動態(tài)庫給我們帶來了什么:
1、開發(fā)時的復用性:成千上萬的各種實用庫,包含它們的頭文件,你就可以開始使用它們提供的功能;
2、編譯時的快捷化:進行過靜態(tài)鏈接編譯的人都知道,其編譯過程的時間消耗是動態(tài)鏈接的數(shù)倍倍甚至更多;
3、部署時的輕量化:如果你的程序使用操作系統(tǒng)自帶的動態(tài)庫,或者是一些非常流行的庫。那么部署你的軟件時,這些庫便可以不用包含在你的
4、packge里面,大大減小了其體積;
使用時的可維護性:某個庫如果發(fā)布了更新的版本,那么你只需替換這個動態(tài)庫文件,而不需要重新編譯你的整個程序。
在如今這個時不時都需要給軟件打補丁的時代,這是相當方便的。那么,她又會給我們帶來什么煩惱呢?軟件的易用性至上。所謂易用性,不單單指這個進入了這個軟件后使用起來多么多么方便,使用之前的那些過程同樣也是易用性的一部分。
用過Linux的可能都會有同感,裝個軟件真難啊,一會兒提示缺這個so庫,一會兒這個so和那個so又不兼容了,還有甚者,你還需要在你的帳戶的配置文件里設置一大堆參數(shù)……還沒安裝完,就已經(jīng)放棄了使用這個軟件的念頭。我想,易用性的問題也是 Linux如此強大可是普及率遠遠不及Windows的根源吧,畢竟絕大多數(shù)的用戶需要的是一個傻瓜相機般的操作系統(tǒng)。
不過在Windows下,常常你也會遇到”某個dll無法找到,程序無法啟動”、”需要.net framework”之類的提示之。懂點軟件知識的,還知道去下載這個缺失的dll庫或者是下載.net的再發(fā)行庫來安裝。但是這已經(jīng)大大違背了軟件易用性的原則,要知道軟件的受眾絕大多數(shù)都是與IT行業(yè)無關的人員,它們遇到這些問題時候便是束手就擒。
Visual Studio 2005后的版本更是不可理喻,它們編譯出來的C/C++程序,如果在沒有Visual Studio再發(fā)行庫的系統(tǒng)上運行,直接提示”應用程序沒有正確配置,重新安裝可能解決該問題”,簡直不知所云……
靜態(tài)鏈接的存在的合理性就在這里,一個可執(zhí)行文件部署給用戶,用戶什么都不用做,雙擊一下就可享用。至于編譯、維護,那是開發(fā)者的事情,哪怕一次編譯要耗費一天的時間,也不能浪費用戶的時間去做一些對他來說不知所云而本可以在開發(fā)者的環(huán)節(jié)中完成的事情。基于以上的信念,我研究了Windows下真正意義上的Qt靜態(tài)庫編譯方法。至于什么叫”真正意義上”,看了下文便知。
Visual Studio相關編譯選項
自己動手編譯過Qt的人可能會覺得奇怪,拿這個問題來寫這么一大段,真是小題大作。Qt的配置選項中不是寫得清楚明白-static便是編譯靜態(tài)庫嗎??墒悄阌姓嬲囘^嗎,用這個靜態(tài)庫編譯的程序拿到一個”干凈”的機器上運行,則提示”應用程序沒有正確配置……”或是”msvcrpxx.dll”沒有找到。 看來Qt是靜態(tài)了,可是Qt是用C++寫的,其中鏈接的C++運行庫還是動態(tài)的。解決這個問題,要從Visual Studio的4個編譯選項說起,它們決定了程序在鏈接階段C/C++庫的鏈接方式。
1、鏈接C/C++多線程動態(tài)庫,使用這些編譯選項,軟件部署時需要VC的再發(fā)行庫,否則就會出現(xiàn)上述錯誤提示。
/MD:動態(tài)鏈接多線程庫(msvcrt.lib)。使用該選項時,需要用/NODEFAULTLIB選項來忽略掉libc.lib、libcmt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib庫,否則會有鏈接錯誤;
/MDd:動態(tài)鏈接多線程調(diào)試庫(msvcrtd.lib)。使用該選項時,需要用/NODEFAULTLIB選項來忽略掉libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib庫,否則會有鏈接錯誤;
2、鏈接C/C++多線程靜態(tài)庫,使用這些編譯選項,軟件部署時不需要VC的再發(fā)行庫。
/MT:靜態(tài)鏈接多線程庫(libcmt.lib)。使用該選項時,需要用/NODEFAULTLIB選項來忽略掉libc.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib庫,否則會有鏈接錯誤;
/MTd:靜態(tài)鏈接多線程調(diào)試庫(libcmtd.lib)。使用該選項時,需要用/NODEFAULTLIB選項來忽略掉libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、msvcrtd.lib庫,否則會有鏈接錯誤。
OK,準備工作就緒,下面開始編譯真正意義上的靜態(tài)Qt庫:-)
編譯靜態(tài)Qt庫
既然找到了解決方法,這個編譯就應該沒問題了吧。可是configure時明明用-static配置了Qt,編譯結(jié)果確仍然事與愿違。仔細查看所生成的 makefile,才發(fā)現(xiàn)編譯選項都是/MD、/MDd。問題就出在這里啦,不過這成千上百個makefile,難道要手動一個個修改……一定有什么東西決定了makefile的生成參數(shù)。不錯!就在Qt根目錄中的mkspecs目錄里,一看名字就知道是make specification的縮寫。該目錄下,各種平臺下的各個編譯器都有一個子目錄。嘿嘿,編譯器的編譯選項就都在這里了,打開win32- msvc2008中的qmake.conf看看,找到了下面兩行嗎:
- [cc lang="make"]
- QMAKE_CFLAGS_RELEASE = -O2 -MD -GL
- QMAKE_CFLAGS_DEBUG = -Zi -MDd
- [/cc]
相信你已經(jīng)知道了問題答案,將它們改成:
- [cc lang="make"]
- QMAKE_CFLAGS_RELEASE = -O2 -MT -GL
- QMAKE_CFLAGS_DEBUG = -Zi -MTd
- [/cc]
同時別忘了加入前面提到的忽略庫選項,修改QMAKE_LFLAGS_RELEASE和QMAKE_LFLAGS_DEBUG參數(shù)為:
- [cc lang="make"]
- QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /LTCG /NODEFAULTLIB:libc.lib /NODEFAULTLIB:msvcrt.lib/NODEFAULTLIB:libcd.lib
- /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib
- QMAKE_LFLAGS_DEBUG = /DEBUG /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib
- /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:msvcrtd.lib
- [/cc]
大功告成,這個時候再在Qt的根目錄下configure -static …(其它選項自行選擇),然后nmake,兩三個小時之后,真正意義上的靜態(tài)Qt庫就產(chǎn)生了。本人有個小建議,其實編譯demos和examples 會消耗非常多時間,你只用cd src然后nmake來編譯Qt庫,如有需要cd tools來編譯諸如QtDesigner之類的工具。
另外webkit庫的編譯是最耗時的,如果你不準備使用這個庫,那么configure加入 -no-webkit,這樣,整個編譯過程大概值耗時40-60分鐘。這時候你可以嘗試建立***個純靜態(tài)的Qt程序,不過當你鏈接的時候,仍然會出現(xiàn)一大堆鏈接錯誤,提示 unresolved external symbol。這個時候你只需要在你的Qt工程文件.pro里面加入:
- [cc lang="make"]
- win32:LIBS += Imm32.lib Winmm.lib ws2_32.lib
- [/cc]
即可。至此,你的”純”靜態(tài)Qt應用程序就可以發(fā)布給用戶啦。
小結(jié):詳解編譯Windows平臺下靜態(tài)Qt庫的內(nèi)容介紹完了,希望通過本文的學習能對你有所幫助!