VS2013編譯Qt5.3.2的靜態庫
針對這個問題網上找到的資料有兩種解決方法,一是將程式需要的庫檔案放在一起,這個顯然很麻煩,而且個人很不喜歡這種方式;另一種就是靜態編譯,所謂靜態編譯,就是編譯器在編譯可執行檔案的時候,將可執行檔案需要呼叫的對應動態連結庫中的部分提取出來,連結到可執行檔案中去,使可執行檔案在執行的時候不依賴於動態連結庫。
下面介紹一下我自己編譯靜態庫的過程,網上資料不少,但是介紹的都不全面,加上我這方面的基礎也不怎麼樣,著實花了一番功夫。
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?- QMAKE_CFLAGS_RELEASE = -O2 -MD
- QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
- QMAKE_CFLAGS_DEBUG = -Zi -MDd
- QMAKE_CFLAGS_RELEASE = -O2 -MT
- QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
- QMAKE_CFLAGS_DEBUG = -Zi -MTd
即將MD(動態)改為MT(靜態)。
5、我的電腦裝的是VS2013,由開始選單開啟Windows Studio Tools,選擇畫紅線的VS2013開發人員命令提示
6、在“VS2013開發人員命令提示”視窗中輸入python:
如果向上圖一樣不認命令,說明環境變數未配置:
輸入:
[plain] view plaincopyprint?- set PATH=%PATH%;F:\Program Files\Python33
再次輸入python,如下圖就OK了:
按下“Ctrl+z”,再回車,退出Python:
轉至Qt解壓目錄,我的是:E:\Qt\qt-everywhere-opensource-src-5.3.1
關鍵步驟:
執行configure:
輸入:
[plain] view plaincopyprint?- 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?- 08:16:16: 為專案untitled執行步驟 ...
- 08:16:16: 正在啟動 "E:\Qt\5.3.1-static-vs2013\bin\qmake.exe" F:\WorkSpace\Qt\untitled\untitled.pro -r -spec win32-msvc2013
- 08:16:17: 程序"E:\Qt\5.3.1-static-vs2013\bin\qmake.exe"正常退出。
- 08:16:17: 正在啟動 "F:\Qt_VS2013_Opengl_x86\Tools\QtCreator\bin\jom.exe"
- F:\Qt_VS2013_Opengl_x86\Tools\QtCreator\bin\jom.exe -f Makefile.Debug
- E:\Qt\5.3.1-static-vs2013\bin\uic.exe ..\untitled\mainwindow.ui -o ui_mainwindow.h
- 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
- main.cpp
- 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
- 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
- untitled_plugin_import.cpp
- 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
- mainwindow.cpp
- 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
- moc_mainwindow.cpp
- echo 1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ "debug\\untitled.exe.embed.manifest">debug\untitled.exe_manifest.rc
- if not exist debug\untitled.exe if exist debug\untitled.exe.embed.manifest del debug\untitled.exe.embed.manifest
- if exist debug\untitled.exe.embed.manifest copy /Y debug\untitled.exe.embed.manifest 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.2496.jom
- 正在建立庫 debug\untitled.lib 和物件 debug\untitled.exp
- 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
- if not exist debug\untitled.exe_manifest.bak rc.exe /fodebug\untitled.exe_manifest.res debug\untitled.exe_manifest.rc
- Microsoft (R) Windows (R) Resource Compiler Version 6.3.9600.16384
- Copyright (C) Microsoft Corporation. All rights reserved.
- 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
- 正在建立庫 debug\untitled.lib 和物件 debug\untitled.exp
- if exist debug\untitled.exe_manifest.bak del debug\untitled.exe_manifest.bak
- 08:16:34: 程序"F:\Qt_VS2013_Opengl_x86\Tools\QtCreator\bin\jom.exe"正常退出。
- 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?- --- (Import): Generating new project of untitled.pro file
- --- (qmake) : Using: e:\qt\5.3.1-static-vs2013\bin\qmake
- --- (qmake) : Working Directory: F:\WorkSpace\Qt\untitled
- --- (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
- --- (qmake) : Exit Code: 0
- --- (Import): Added untitled.vcxproj to Solution
- === Update uic steps ===
- Update uic step for mainwindow.ui.
- === 1 uic steps updated. ===
- === Update rcc steps ===
- === 0 rcc steps updated. ===
Ctrl+F5,成功彈出一個視窗: [plain] view plaincopyprint?
- 還原 NuGet 程式包時出錯: System.ArgumentException: 路徑的形式不合法。
- 在 System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
- 在 System.IO.Path.GetDirectoryName(String path)
- 在 NuGet.VisualStudio.VsUtility.GetNuGetSolutionFolder(Solution solution)
- 在 NuGet.VsEvents.PackageRestorer.UsingOldPackageRestore(Solution solution)
- 在 NuGet.VsEvents.PackageRestorer.BuildEvents_OnBuildBegin(vsBuildScope Scope, vsBuildAction Action)。
- 1>------ 已啟動生成: 專案: untitled, 配置: Debug Win32 ------
- 1> Moc'ing mainwindow.h...
- 1> Uic'ing mainwindow.ui...
- 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.
- 1> moc_mainwindow.cpp
- 1> main.cpp
- 1> mainwindow.cpp
- 1> untitled_plugin_import.cpp
- 1> 正在生成程式碼...
- 1> 正在建立庫 debug\\untitled.lib 和物件 debug\\untitled.exp
- 1> untitled.vcxproj -> F:\WorkSpace\Qt\untitled\debug\untitled.exe
- ========== 生成: 成功 1 個,失敗 0 個,最新 0 個,跳過 0 個 ==========
OK,這篇文章終於寫完了,稍後我會將編譯好的靜態庫傳至網盤,有需要的可以自行下載。
Qt 5.3.1 靜態連結庫:(儲存連結圖片,改副檔名為.7z,即為下載地址)