先從Windows平臺開始。 Windows平臺下的軟件發佈最主要的需求是想辦法找到在你的發佈中應該包含哪些必須的文件, 同時要保證應用程序運行時能正確找到這些文件, 發佈基於Qt的軟件也是一樣的需求。 就不一樣的狀況一一闡述: redis
靜態連接的狀況 數據庫
靜態連接是最簡單的狀況,這種狀況下須要發佈的文件數量是最少的, 只須要發佈一個單獨的執行檔外加編譯器相關的dll文件。 這種狀況下Qt庫首先要靜態編譯: windows
configure -static [other options] app
nmake sub-src ide
//若是用mingw編譯,nmake替換成mingw32-make 函數
//sub-src指只編譯src目錄,這樣省去編譯examples等目錄的時間 工具
注意哦,若是你在同一個build目錄用不一樣的configure選項去編譯Qt, 必須在從新configure以前運行nmake distclean清除之前生成的目標和中間文件, 保證一個乾淨的編譯環境,否則有可能會出一些奇怪的連接錯誤哦~~ 測試
編譯好Qt靜態庫下一步再編譯應用程序: 網站
cd application_dir ui
nmake clean
qmake -config release
nmake
編譯成功以後應該獲得一個能夠獨立執行的exe文件, 能夠將程序拷貝到其餘沒有安裝qt的機器上測試。 須要注意的是這個程序不必定百分之百能夠運行,由於編譯器帶的庫仍然是動態編譯的,若是你的目標機裏沒有這些庫的話仍然會有運行時的問題。 後面會講到如何用工具來檢查應用程序的依賴。
靜態連接方法比較重要的缺陷是沒法支持插件, 並且插件不能編譯進程序中,因此插件提供的功能就丟失了。 這樣一來要想用到插件的功能仍是要用下面的方法。
動態連接的狀況
動態連接程序的發佈須要解決兩個問題, Qt庫須要與應用一塊兒發佈, 另外插件也要一塊兒打包,並保證放在適當的位置, 這樣應用程序才能找到它。
動態編譯應用的基礎是先將Qt庫動態編譯(默認參數便是動態編譯),這樣用普通的程序編譯流程就可生成動態編譯的執行檔,使用的命令與上面相同。 咱們能夠用一個Qt的例子測試前面說的發佈方法, 在Qt包裏帶的例子Plug & Paint
是個很是合適的測試例子,它既包含應用又自帶插件文件, 能夠很好的驗證發佈是否正確。 該例子在examples/tools/plugandpaint下。 這個例子若是編譯成功, 獲得一個plugandpaint.exe和pnp_basictools.dll、pnp_extrafilters.dll兩個插件文件。
程序打包
第一步,將應用程序和Qt庫拷貝到同一目錄。(Windows下庫的搜索先從當前目錄開始,而後是在系統PATH環境變量指定的路徑查找。)
第二步,檢查應用程序還依賴哪些dll,如編譯器帶的dll或其餘系統dll。 參見應用程序的依賴關係一節。
第三步,驗證程序能夠在目標系統上正確運行, 將目前包裏的文件拷貝到目標系統上,嘗試運行程序。
第四步,發佈插件程序。 插件和普通的動態庫的發佈不一樣, 不能簡單的將之拷貝到應用目錄裏。 應用程序在運行時會在其對應的plugins目錄下去查找插件。 針對這個例子,發佈包應該相似這樣的結構:
模塊 |
文件名 |
執行檔 | plugandpaint.exe |
Basic Tool插件 | plugins\pnp_basictools.dll |
ExtraFilters插件 | plugins\pnp_extrafilters.dll |
Qt Core模塊 | qtcore4.dll |
Qt Gui模塊 | qtgui4.dll |
除了程序和Qt庫,還有下面的編譯器庫:
VC++ 6.0 |
VC++ 7.1 (2003) |
VC++ 8.0 (2005) |
|
C運行庫 | msvcrt.dll | msvcr71.dll | msvcr80.dll |
C++運行庫 | msvcp60.dll | msvcp71.dll | msvcp80.dll |
插件的位置除了Qt默認的路徑還能夠經過代碼裏調用Qt的API來指定, 相應的API是QApplication::addLibraryPath()或QApplication::addLibraryPaths(). 如:
qApp->addLibraryPath(「c:\some\path」);
上述代碼的推薦調用位置是在main函數中,QApplication構造完畢以後。 應用程序會在搜索默認路徑以後去搜索你指定的庫路徑。
Visual Studio 2005
vs2005編譯的程序在發佈的時候還須要考慮一些額外的狀況,比較麻煩點。 要把manifest文件拷貝到應用程序的目錄, 這個文件包含應用的依賴信息, 在運行時須要用到。 另外,若是你的動態庫的依賴和應用不一樣,那麼還須要把manifest文件內嵌到dll文件中。 Qt4.1.3以後的版本提供了CONFIG選項來提供內嵌manifest文件的功能, embed_manifest_dll和embed_manifest_exe, 用法是將下面的選項加入pro文件, 以下:
CONFIG+=embed_manifest_exe
默認狀況下embed_manifest_dll已經開啓。 關於manifest文件的更多信息參考MSDN的相關文章。
有兩種發佈vc運行庫的方法, 一個是安裝vs的運行庫到目標系統中, 另外是將庫打包到應用程序的目錄。 打包vs運行庫很簡單,就是把 <Visual Studio Install Path>\VC\redist\<Architecture>\Microsoft.VC80.CRT拷貝到應用程序目錄,與應用程序一塊兒打包。 若是你在打包運行庫的同時還要發佈插件程序,要注意把manifest文件從插件中去掉,否則在一些系統上會致使插件沒法加載。 去掉manifest的方法是在插件的pro文件中加入下面的選項:
CONFIG-=embed_manifest_dll
VS系統的運行包能夠免費得到, 只須要將這個安裝包和你的應用安裝包一塊兒發佈,而且在安裝你的程序的時候去運行這個安裝包就好了。 好比32位的x86系統, 安裝32bit-x86-vs運行時包。 其餘平臺對應的包能夠在微軟網站找到。
應用程序的依賴關係
用這個工具檢查上面的例子, 發現下面的庫不是系統自帶的:
Qt |
VC++ 6.0 |
VC++ 7.1 (2003) |
VC++ 8.0 (2005) |
MinGW |
QTCORE4.DLL QTGUI4.DLL |
MSVCRT.DLL MSVCP60.DLL |
MSVCR71.DLL MSVCP71.DLL |
MSVCR80.DLL MSVCP80.DLL |
MINGWM10.DLL(若是用mingw來編譯的話須要這個庫) |
別忘了也檢查一下plugin庫的依賴。
Qt自帶的插件
不少狀況下,咱們的程序還依賴Qt帶的一些插件,好比圖像格式的支持或數據庫驅動支持等。 這些插件須要放在plugins的特定子目錄下, 如圖像格式插件在plugins\imageformat下. Qt搜索插件的默認路徑是QTDIR\plugins, 這個路徑已經寫入了Qt庫中, 但咱們能夠經過如下幾種方法來override這個路徑。
編輯qt.conf文件,推薦的方法(後面將寫一篇關於qt.conf的帖子)http://www.cuteqt.com/blog/?p=149
用前面提到的QApplication::addLibraryPath函數 使用第三方的工具修改QtCore庫裏寫入的路徑 Qt文檔裏有一篇專門寫插件的文章,若是你在編譯和發佈插件時遇到了問題,參考 How to Create Qt Plugins