如何打包發佈基於Qt4 Windows的軟件

如何打包發佈基於Qt4 Windows的軟件

先從Windows平臺開始。 Windows平臺下的軟件發佈最主要的需求是想辦法找到在你的發佈中應該包含哪些必須的文件, 同時要保證應用程序運行時能正確找到這些文件, 發佈基於Qt的軟件也是同樣的需求。 就不同的情況一一闡述:

靜態鏈接的情況

靜態鏈接是最簡單的情況,這種情況下需要發佈的文件數量是最少的, 只需要發佈一個單獨的執行檔外加編譯器相關的dll文件。 這種情況下Qt庫首先要靜態編譯:

< [other -static>

nmake sub-src

//如果用mingw編譯,nmake替換成mingw32-make
//sub-src指只編譯src目錄,這樣省去編譯examples等目錄的時間

注意哦,如果你在同一個build目錄用不同的configure選項去編譯Qt,  必須在重新configure之前運行nmake distclean清除以前生成的目標和中間文件, 保證一個乾淨的編譯環境,不然有可能會出一些奇怪的鏈接錯誤哦~~

編譯好Qt靜態庫下一步再編譯應用程序:
cd application_dir
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運行時包。 其他平臺對應的包可以在微軟網站找到。

應用程序的依賴關係

額外的依賴庫

這裏我們的祕密武器終於隆重登場了! 那就是 Dependency Walker工具。 看一張截圖:

deployment-windows-depends

用這個工具檢查上面的例子, 發現下面的庫不是系統自帶的:

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這個路徑。

  1. 編輯qt.conf文件,推薦的方法(後面將寫一篇關於qt.conf的帖子)
  2. 用前面提到的QApplication::addLibraryPath函數
  3. 使用第三方的工具修改QtCore庫裏寫入的路徑

原文鏈接:http://blog.163.com/lijiji_1515/blog/static/1268774462009103103458507/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章