1. 程式人生 > >VS2013編譯Qt5.3.2的靜態庫

VS2013編譯Qt5.3.2的靜態庫

今天用Qt寫了個小程式,拷到另一臺電腦發現無法執行,缺少檔案。查了一下資料,發現是動態連結庫的問題,因為原來一直用的微軟系列的開發工具,這個問題不怎麼突出,現在用Qt寫程式,這個問題就很麻煩了。

    針對這個問題網上找到的資料有兩種解決方法,一是將程式需要的庫檔案放在一起,這個顯然很麻煩,而且個人很不喜歡這種方式;另一種就是靜態編譯,所謂靜態編譯,就是編譯器在編譯可執行檔案的時候,將可執行檔案需要呼叫的對應動態連結庫中的部分提取出來,連結到可執行檔案中去,使可執行檔案在執行的時候不依賴於動態連結庫

    下面介紹一下我自己編譯靜態庫的過程,網上資料不少,但是介紹的都不全面,加上我這方面的基礎也不怎麼樣,著實花了一番功夫。

不多廢話,開始介紹:

1、下載Qt5.3.1的原始碼:qt-everywhere-opensource-src-5.3.1.zip

開啟官網下載頁面,點選紅線畫著的文字“zip”下載原始碼:http://qt-project.org/downloads


儲存圖片,改字尾為7z,有下載網址

2、安裝python:https://www.python.org/downloads/


儲存圖片,改字尾為7z,有下載網址

2.1安裝Ruby:http://rubyinstaller.org/downloads/

安裝時選擇以下2項:


2.2安裝Perl:http://www.activestate.com/activeperl/downloads

最後再檢查有沒有將以上安裝後的工具都新增到系統變數中,如:Path = “C:\Perl64\site\bin;C:\Perl64\bin;C:\python34;C:\Ruby21-x64\bin”

3、下載完成後解壓,注意硬碟的可用空間:

我的解壓目錄是:E:\Qt

這是我編譯完的資料夾大小(包括編譯目錄和install目錄):


4、根據你的VS版本進入相應的資料夾,我是win32-msvc2013:


進入E:\Qt\qt-everywhere-opensource-src-5.3.1\qtbase\mkspecs\win32-msvc2013目錄,有兩個檔案:


開啟qmake.conf,修改內容並儲存,如下:

原內容:

[plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. QMAKE_CFLAGS_RELEASE    = -O2 -MD  
  2. QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi  
  3. QMAKE_CFLAGS_DEBUG      = -Zi -MDd  
修改為: [plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. QMAKE_CFLAGS_RELEASE    = -O2 -MT  
  2. QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi  
  3. QMAKE_CFLAGS_DEBUG      = -Zi -MTd  

即將MD(動態)改為MT(靜態)。

5、我的電腦裝的是VS2013,由開始選單開啟Windows Studio Tools,選擇畫紅線VS2013開發人員命令提示


6、在“VS2013開發人員命令提示”視窗中輸入python:


如果向上圖一樣不認命令,說明環境變數未配置:

輸入:

[plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. set PATH=%PATH%;F:\Program Files\Python33  
注:F:\Program Files\Python33是Python的安裝目錄(與我的肯定不同,我不是安裝在預設位置的,預設位置是C:\Python33)

再次輸入python,如下圖就OK了:



按下“Ctrl+z”,再回車,退出Python:


轉至Qt解壓目錄,我的是:E:\Qt\qt-everywhere-opensource-src-5.3.1


關鍵步驟

執行configure:

輸入:

[plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. configure -confirm-license -opensource -platform win32-msvc2013 -debug-and-release -static -prefix "E:\Qt\5.3.1-static-vs2013" -qt-sql-sqlite -qt-sql-odbc -plugin-sql-sqlite -plugin-sql-odbc -qt-zlib -qt-libpng -qt-libjpeg -opengl desktop -qt-freetype -no-qml-debug -no-angle -nomake tests -nomake examples -skip qtwebkit  

其中”E:\Qt\5.3.1-static-vs2013“為編譯完後的安裝目錄。


回車執行,一會後執行完畢:


7、接下來,執行nmake:

回車,然後是漫長的等待,估計2個多小時吧,因為我晚上執行後就去睡了,具體多少時間不清楚。

8、nmake完成,整個過程沒出什麼錯,接著就可以install了,輸入nmake install命令:

至此Qt5.3.1的靜態庫靜態庫編譯完成,接下去就是測試能不能使用了。

9、開啟Qt Creator5.3,工具->選項->構建路徑->Qt Versions->新增剛才的安裝目錄:


10、切換到 構建套件(Kit)選項卡,新增,這裡我取名為”Qt 5.3 static“,更改”Qt 版本“為剛才新增的編譯完的靜態版

11、新建一個Qt Widgets Application:


一路預設配置,下一步:

在配置Kit的時候會顯示兩個,Static就是靜態版的,為了做對比,兩個都勾選:


12、先用動態的編譯(debug和release):


13、再用靜態的編譯(同樣debug和release):


下面是靜態編譯debug版時的編譯輸出,我們看到啟動的是E盤下面的qmake,也就是我們編譯輸出的靜態連結庫:

[plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. 08:16:16: 為專案untitled執行步驟 ...  
  2. 08:16:16: 正在啟動 "E:\Qt\5.3.1-static-vs2013\bin\qmake.exe" F:\WorkSpace\Qt\untitled\untitled.pro -r -spec win32-msvc2013  
  3. 08:16:17: 程序"E:\Qt\5.3.1-static-vs2013\bin\qmake.exe"正常退出。  
  4. 08:16:17: 正在啟動 "F:\Qt_VS2013_Opengl_x86\Tools\QtCreator\bin\jom.exe"   
  5.     F:\Qt_VS2013_Opengl_x86\Tools\QtCreator\bin\jom.exe -f Makefile.Debug  
  6.     E:\Qt\5.3.1-static-vs2013\bin\uic.exe ..\untitled\mainwindow.ui -o ui_mainwindow.h  
  7.     cl -c -nologo -Zm200 -Zc:wchar_t -FS -Zi -MTd -GR -W3 -w34100 -w34189 -EHsc /Fddebug\untitled.pdb -DUNICODE -DWIN32 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I"E:\Qt\5.3.1-static-vs2013\include" -I"E:\Qt\5.3.1-static-vs2013\include\QtWidgets" -I"E:\Qt\5.3.1-static-vs2013\include\QtGui" -I"E:\Qt\5.3.1-static-vs2013\include\QtCore" -I"debug" -I"." -I"." -I"E:\Qt\5.3.1-static-vs2013\mkspecs\win32-msvc2013" -Fodebug\ @C:\Users\Kaven\AppData\Local\Temp\main.obj.1064.0.jom  
  8. main.cpp  
  9.     cl -c -nologo -Zm200 -Zc:wchar_t -FS -Zi -MTd -GR -W3 -w34100 -w34189 -EHsc /Fddebug\untitled.pdb -DUNICODE -DWIN32 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I"E:\Qt\5.3.1-static-vs2013\include" -I"E:\Qt\5.3.1-static-vs2013\include\QtWidgets" -I"E:\Qt\5.3.1-static-vs2013\include\QtGui" -I"E:\Qt\5.3.1-static-vs2013\include\QtCore" -I"debug" -I"." -I"." -I"E:\Qt\5.3.1-static-vs2013\mkspecs\win32-msvc2013" -Fodebug\ @C:\Users\Kaven\AppData\Local\Temp\untitled_plugin_import.obj.1064.16.jom  
  10.     E:\Qt\5.3.1-static-vs2013\bin\moc.exe -DUNICODE -DWIN32 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1800 -D_WIN32 -IE:/Qt/5.3.1-static-vs2013/mkspecs/win32-msvc2013 -IF:/WorkSpace/Qt/untitled -IE:/Qt/5.3.1-static-vs2013/include -IE:/Qt/5.3.1-static-vs2013/include/QtWidgets -IE:/Qt/5.3.1-static-vs2013/include/QtGui -IE:/Qt/5.3.1-static-vs2013/include/QtCore -I. ..\untitled\mainwindow.h -o debug\moc_mainwindow.cpp  
  11. untitled_plugin_import.cpp  
  12.     cl -c -nologo -Zm200 -Zc:wchar_t -FS -Zi -MTd -GR -W3 -w34100 -w34189 -EHsc /Fddebug\untitled.pdb -DUNICODE -DWIN32 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I"E:\Qt\5.3.1-static-vs2013\include" -I"E:\Qt\5.3.1-static-vs2013\include\QtWidgets" -I"E:\Qt\5.3.1-static-vs2013\include\QtGui" -I"E:\Qt\5.3.1-static-vs2013\include\QtCore" -I"debug" -I"." -I"." -I"E:\Qt\5.3.1-static-vs2013\mkspecs\win32-msvc2013" -Fodebug\ @C:\Users\Kaven\AppData\Local\Temp\mainwindow.obj.1064.47.jom  
  13. mainwindow.cpp  
  14.     cl -c -nologo -Zm200 -Zc:wchar_t -FS -Zi -MTd -GR -W3 -w34100 -w34189 -EHsc /Fddebug\untitled.pdb -DUNICODE -DWIN32 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I"E:\Qt\5.3.1-static-vs2013\include" -I"E:\Qt\5.3.1-static-vs2013\include\QtWidgets" -I"E:\Qt\5.3.1-static-vs2013\include\QtGui" -I"E:\Qt\5.3.1-static-vs2013\include\QtCore" -I"debug" -I"." -I"." -I"E:\Qt\5.3.1-static-vs2013\mkspecs\win32-msvc2013" -Fodebug\ @C:\Users\Kaven\AppData\Local\Temp\moc_mainwindow.obj.1064.328.jom  
  15. moc_mainwindow.cpp  
  16.     echo 1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ "debug\\untitled.exe.embed.manifest">debug\untitled.exe_manifest.rc  
  17.     if not exist debug\untitled.exe if exist debug\untitled.exe.embed.manifest del debug\untitled.exe.embed.manifest  
  18.     if exist debug\untitled.exe.embed.manifest copy /Y debug\untitled.exe.embed.manifest debug\untitled.exe_manifest.bak  
  19.     link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\untitled.exe.embed.manifest /OUT:debug\untitled.exe @C:\Users\Kaven\AppData\Local\Temp\untitled.exe.1064.2496.jom  
  20.    正在建立庫 debug\untitled.lib 和物件 debug\untitled.exp  
  21.     if exist debug\untitled.exe_manifest.bak fc /b debug\untitled.exe.embed.manifest debug\untitled.exe_manifest.bak >NUL || del debug\untitled.exe_manifest.bak  
  22.     if not exist debug\untitled.exe_manifest.bak rc.exe /fodebug\untitled.exe_manifest.res debug\untitled.exe_manifest.rc  
  23. Microsoft (R) Windows (R) Resource Compiler Version 6.3.9600.16384  
  24. Copyright (C) Microsoft Corporation.  All rights reserved.  
  25.     if not exist debug\untitled.exe_manifest.bak link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\untitled.exe.embed.manifest /OUT:debug\untitled.exe @C:\Users\Kaven\AppData\Local\Temp\untitled.exe.1064.2512.jom  
  26.    正在建立庫 debug\untitled.lib 和物件 debug\untitled.exp  
  27.     if exist debug\untitled.exe_manifest.bak del debug\untitled.exe_manifest.bak  
  28. 08:16:34: 程序"F:\Qt_VS2013_Opengl_x86\Tools\QtCreator\bin\jom.exe"正常退出。  
  29. 08:16:34: Elapsed time: 00:18.  

開啟專案路徑,內容如下:


同樣的原始碼,編譯後的結果比較:

先看debug版:

靜態:大小隻有82k


動態:21.5M


再看release版:

動態:23.5k



靜態:9.33M


這4個程式的功能都一樣,就是彈出一個視窗:

但是你會發現將4個檔案單獨複製出來,雙擊執行,動態生成的是無法在未安裝Qt連結庫環境的電腦上執行的:

我雖然裝了Qt,但是沒有設定環境變數,所以動態編譯的單檔案(無論是debug版還是release版)還是無法執行,錯誤如下:


但是,靜態編譯的就不同了,在任何一臺普通電腦上,直接就能執行,當然代價是執行檔案變大:


14、最後,用VS2013編譯原始檔,需要安裝一個Qt外掛,

開啟VS2013,新增靜態庫的目錄:



匯入剛才那個用Qt Creator建立的彈出視窗的工程:


匯入時的輸出資訊:

[plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. --- (Import): Generating new project of untitled.pro file  
  2. --- (qmake) : Using: e:\qt\5.3.1-static-vs2013\bin\qmake  
  3. --- (qmake) : Working Directory: F:\WorkSpace\Qt\untitled  
  4. --- (qmake) : Arguments: -tp vc "untitled.pro" -o "untitled.vcxproj" QMAKE_INCDIR_QT=$(QTDIR)\include QMAKE_LIBDIR=$(QTDIR)\lib QMAKE_MOC=$(QTDIR)\bin\moc.exe QMAKE_QMAKE=$(QTDIR)\bin\qmake.exe  
  5. --- (qmake) : Exit Code: 0  
  6. --- (Import): Added untitled.vcxproj to Solution  
  7. === Update uic steps ===  
  8. Update uic step for mainwindow.ui.  
  9. === 1 uic steps updated. ===  
  10. === Update rcc steps ===  
  11. === 0 rcc steps updated. ===  

Ctrl+F5,成功彈出一個視窗: [plain] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. 還原 NuGet 程式包時出錯: System.ArgumentException: 路徑的形式不合法。  
  2.    在 System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)  
  3.    在 System.IO.Path.GetDirectoryName(String path)  
  4.    在 NuGet.VisualStudio.VsUtility.GetNuGetSolutionFolder(Solution solution)  
  5.    在 NuGet.VsEvents.PackageRestorer.UsingOldPackageRestore(Solution solution)  
  6.    在 NuGet.VsEvents.PackageRestorer.BuildEvents_OnBuildBegin(vsBuildScope Scope, vsBuildAction Action)。  
  7. 1>------ 已啟動生成:  專案: untitled, 配置: Debug Win32 ------  
  8. 1>  Moc'ing mainwindow.h...  
  9. 1>  Uic'ing mainwindow.ui...  
  10. 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(935,5): warning MSB8027: Two or more files with the name of moc_mainwindow.cpp will produce outputs to the same location. This can lead to an incorrect build result.  The files involved are GeneratedFiles\Debug\moc_mainwindow.cpp, GeneratedFiles\Release\moc_mainwindow.cpp.  
  11. 1>  moc_mainwindow.cpp  
  12. 1>  main.cpp  
  13. 1>  mainwindow.cpp  
  14. 1>  untitled_plugin_import.cpp  
  15. 1>  正在生成程式碼...  
  16. 1>     正在建立庫 debug\\untitled.lib 和物件 debug\\untitled.exp  
  17. 1>  untitled.vcxproj -> F:\WorkSpace\Qt\untitled\debug\untitled.exe  
  18. ========== 生成:  成功 1 個,失敗 0 個,最新 0 個,跳過 0 個 ==========  


OK,這篇文章終於寫完了,稍後我會將編譯好的靜態庫傳至網盤,有需要的可以自行下載。

Qt 5.3.1 靜態連結庫:(儲存連結圖片,改副檔名為.7z,即為下載地址)