1. 程式人生 > >Qt5.11.2 & VS2017 & 64位版本靜態編譯及使用

Qt5.11.2 & VS2017 & 64位版本靜態編譯及使用

Qt5.11.2 & VS2017 & 64位版本 靜態編譯

小夥伴們有沒有遇到過,自己使用Qt庫開發的小程式,在本地電腦上跑得很歡快,但是當想要把編譯好的.exe可執行檔案發給朋友玩玩的時候,發現在沒有安裝Qt或者VS環境的電腦上是跑不了的。究其原因,這是因為大家在編譯程式時,使用的是動態編譯。也就是說,編譯好的程式在執行時還需要另外加上相應的DLL庫檔案,否則就會出錯。而如果想將生成的程式連同所需要的依賴庫一起完整地打包成一個.exe可執行程式,那就需要使用靜態編譯。

1、問題描述:

使用VS編譯程式時,執行庫選擇多執行緒(/MT),表示採用多執行緒靜態release

的方式進行編譯。
在這裡插入圖片描述
但是,發現編譯是不能通過的。

qtmain.lib(qtmain_win.obj) : error LNK2038: 檢測到“RuntimeLibrary”的不匹配項: 值“MD_DynamicRelease”不匹配值“MT_StaticRelease”

原因在於安裝Qt時預設使用的是動態庫,而且官方並沒有提供編譯好的靜態庫下載。
但我們可以自己下載Qt原始碼下來,自己重新編譯,生成靜態庫,這樣我們開發的Qt程式也就能完成靜態的編譯了。以後也就只需要編譯成一個exe,就能滿地跑了哈~(自己動手嘗試一下,還是挺好玩的)

2、下載原始碼包

首先,我們需要從Qt官網(地址:

http://download.qt.io/archive/qt/5.11/5.11.2/single/ )下載對應的Qt原始碼。在這裡,我以在Windows下編譯Qt程式為例。
在這裡插入圖片描述
下載後是一個壓縮檔案,將它解壓到一個空間較大的磁碟下面。一會靜態編譯需要佔用大量磁碟空間。(謹慎起見,請至少保證該磁碟下有10G左右空間。)
在這裡插入圖片描述

3、編譯環境

以下是編譯時需要的工具,在編譯之前,請務必安裝!
安裝都比較簡單。這裡直接給出官網下載的連結。最後記得新增到環境變數(安裝時把‘’新增到PATH環境“選項勾起就可以了,或者在安裝後手動新增也可以)。

建議安裝jom,來替換nmake進行編譯,可以充分利用CPU多核的能力,否則估計你會中途吐血的。
jom是nmake的多執行緒版,nmake不支援多執行緒,單執行緒編譯速度太慢了。

4、編譯原始碼庫

以上東西都準備好以後,接下來我們可以開始編譯原始碼了。

  1. 在編譯之前記得先將所有的防毒軟體關掉(避免誤殺)。

  2. 然後進入解壓後的Qt原始碼資料夾下的qtbase/mkspecs下,找到win32-msvc資料夾。在這裡插入圖片描述

  3. 另外順便說下,如果是想編譯較早些時候的Qt原始碼,原始碼下載下來後會發現裡面沒有這個資料夾。而是這樣的:
    在這裡插入圖片描述
    這時候只需要根據你安裝的Qt版本進行選擇就可以了。

  4. 進入選中的資料夾之後,找到qmake.conf檔案並使用文字編輯器開啟。

  5. 我們再根據它include的內容定位到相應的檔案。

    include(../common/msvc-desktop.conf)
    
  6. 找到相應的檔案後,修改其內容。在這裡也就是msvc-desktop.conf這個檔案。

    找到以下標誌。將原來的:

    QMAKE_CFLAGS_RELEASE    = $$QMAKE_CFLAGS_OPTIMIZE -MD
    QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -Zi -MD
    QMAKE_CFLAGS_DEBUG      = -Zi -MDd
    

    修改成:

    QMAKE_CFLAGS_RELEASE    = $$QMAKE_CFLAGS_OPTIMIZE -MT
    QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -Zi -MT
    QMAKE_CFLAGS_DEBUG      = -Zi -MTd
    

    即將MD改成MT,MDd改成MTd,動態改成靜態

  7. 在開始選單中,找到“適用於 VS 2017 的 x64 本機工具命令提示“ 或者 “x64 Native Tools Command Prompt for VS 2017”。
    在這裡插入圖片描述

  8. 將當前目錄切換到原始碼解壓後的目錄下。比如我的是在E盤下的qt-everywhere-src-5.11.2這個資料夾。
    在這裡插入圖片描述

  9. 接下來,將執行關鍵的幾個命令。首先執行configure命令。複製並執行以下命令:

    configure.bat -mp -confirm-license -opensource -platform win32-msvc -debug-and-release -static -force-asserts -prefix E:\Qt5.11.2\Qt-msvc2017-x64-static -static-runtime -silent -opengl desktop -qt-sqlite -qt-pcre -qt-zlib -qt-freetype -qt-harfbuzz -qt-libpng -qt-libjpeg -nomake examples -nomake tests

    · 其中 -platform win32-msvc 在前面也有提到過的,根據我們安裝Qt的版本選擇即可;
    · -static 表示編譯靜態庫;
    · E:\Qt5.11.2\Qt-msvc2017-x64-static 是編譯完後的安裝目錄,此目錄不需要事先建立,建議路徑不要太長。
    這個過程不需要很久,執行完結果如圖:
    在這裡插入圖片描述

  10. 執行jom命令。(這時候可以先去喝杯咖啡或者做做其他事情~~ )

  11. jom執行完畢之後,最後再輸入jom install安裝。 如果沒有意外,那麼我們就會在之前設定好的路徑下看到編譯好的檔案。
    在這裡插入圖片描述
    至此,整個Qt原始碼編譯過程也就結束了(過程說簡單也簡單,但我卻搞了兩三天,就因為前面環境沒搭好
    但別高興得太早,這還沒結束呢。。我們必須得建立一個測試程式執行起來才算成功!

4、安裝和配置

  • VS2017中Qt外掛安裝教程

  • 點選選單欄上的“Qt VS Tools > Qt Options”開啟Qt選項視窗;
    在這裡插入圖片描述

  • 然後將我們編譯好的Qt版本(E:\Qt5.11.2\Qt-msvc2017-x64-static)新增進來。
    在這裡插入圖片描述

  • 我們建立一個Qt應用程式進行測試。
    在這裡插入圖片描述

  • 整理遇到的問題。

    使用Release方式編譯,編譯不通過!
    錯誤一:

    Qt5Core.lib(qobject.obj) : error LNK2038: 檢測到“RuntimeLibrary”的不匹配項: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”(main.obj 中)

    原因及解決方法:

    • 因為我們編譯的Qt5.11.2的VC執行庫是MT和MTd,工程嚮導建立的預設是MD和MDd。也就是我們需要把執行庫對應的值改了。

    錯誤二:

    LINK : warning LNK4098: 預設庫“LIBCMT”與其他庫的使用衝突;請使用 /NODEFAULTLIB:library

    原因及解決方法:

    • 在同一個專案中,所有的原始檔必須連結相同的VC執行時庫。如果某一檔案用了MTd版本,而其他檔案用MT版本的庫,也就是說用了不同的庫,就會導致這個警告的出現。 新增一下命令列可解決: 在這裡插入圖片描述
      /NODEFAULTLIB:“libcmt.lib”

    錯誤三:

    Qt5Core.lib(qglobal.obj) : error LNK2019: 無法解析的外部符號 gethostname,該符號在函式 “public: static class QString __cdecl QSysInfo::machineHostName(void)” ([email protected]@@[email protected]@XZ) 中被引用
    Qt5Core.lib(qglobal.obj) : error LNK2019: 無法解析的外部符號 WSAStartup,該符號在函式 “public: __cdecl QWindowsSockInit::QWindowsSockInit(void)” ([email protected]@[email protected]) 中被引用
    Qt5Core.lib(qglobal.obj) : error LNK2019: 無法解析的外部符號 WSACleanup,該符號在函式 “public: __cdecl QWindowsSockInit::~QWindowsSockInit(void)” ([email protected]@[email protected]) 中被引用

    原因及解決方法:
    顯然,這是因為有些依賴庫我們沒新增好~

    • 附加庫目錄改成:$(QTDIR)\lib; $(QTDIR)\plugins\imageformats; $(QTDIR)\plugins\platforms;%(AdditionalLibraryDirectories) 在這裡插入圖片描述

    • 附加依賴項改成:qtmain.lib;qwindows.lib;Qt5Widgets.lib;Qt5Core.lib;Qt5Gui.lib;Qt5PlatformCompositorSupport.lib;Qt5EventDispatcherSupport.lib;Qt5FontDatabaseSupport.lib;Qt5ThemeSupport.lib;Qt5WindowsUIAutomationSupport.lib;qgif.lib;qicns.lib;qico.lib;qjpeg.lib;qsvg.lib;qtga.lib;qtiff.lib;qwbmp.lib;qwebp.lib;qtfreetype.lib;qtharfbuzz.lib;qtlibpng.lib;qtopenwnn.lib;qtpcre2.lib;qttcime.lib;winspool.lib;shlwapi.lib;rpcrt4.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;glu32.lib;opengl32.lib;gdi32.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;mpr.lib;%(AdditionalDependencies)
      在這裡插入圖片描述

      • 在main.cpp檔案中加入程式碼:
          #pragma comment(lib, "version.lib")
          #pragma comment(lib, "Netapi32.lib")
          #pragma comment(lib, "userenv.lib")
          #pragma comment(lib, "msvcrtd.lib")
          #pragma comment(lib, "Dwmapi.lib")
      

    距離成功我們又進一步了,繼續編譯。。


    錯誤四:
    在這裡插入圖片描述

    qt.qpa.plugin: Could not find the Qt platform plugin “windows” in “”
    This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

    原因及解決方法:

    • 外掛無法載入,載入plugin的辦法:
      使用巨集 Q_IMPORT_PLUGIN,在main.cpp中增加程式碼如下:

      	#include <QtCore/QtPlugin>
      	Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
      

繼續執行,發現可以了~ 成功了!
在這裡插入圖片描述