Qt5.11.2 & VS2017 & 64位版本静态编译及使用

Qt5.11.2 & VS2017 & 64位版本 静态编译

1、问题描述:

小伙伴们有没有也遇到过,自己使用Qt库开发的小程序,在自己电脑上跑得很欢快。
但当想要把编译好的.exe可执行文件发给朋友玩玩的时候,发现在没有安装Qt或者VS环境的电脑上是跑不了的。
究其原因,这是因为大家在编译程序时,大多使用的是动态编译。
简单来讲,就是编译好的程序在运行时另外还需要加上一堆的dll库文件,否则运行就会报错。
如果想将生成的程序连同所需要的依赖库一起完整地打包成一个.exe可执行程序,那就需要使用静态编译的方式。

然而,当使用VS编译Qt程序时,运行库选择多线程(/MT)(表示采用多线程静态链接库的方式)进行编译时,
发现编译是不能通过的。会有如下的错误提示:

Qqtmain.lib(qtmain_win.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MT_StaticRelease”

原因在于安装Qt时默认使用的是动态库(而我们却用静态库的方式编译,明显是不对的)。
如果想使用静态库编译,可以自己将Qt源码下载下来,自己动手重新编译,生成静态库。
这样以后也就只需要一个exe,就能随处运行了哈~

2、下载源码包

首先,我们需要从Qt官网(地址:http://download.qt.io/archive/qt/5.11/5.11.2/single/ )下载对应的Qt源码。在这里,我以在Windows下编译Qt程序为例。
Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第1张图片
下载后是一个压缩文件,将它解压到一个空间较大的磁盘下面。一会静态编译需要占用大量磁盘空间。(谨慎起见,请至少保证该磁盘下有10G左右空间。)
在这里插入图片描述

3、编译环境

以下是编译时需要的工具,在编译之前,请务必安装!
安装都比较简单。这里直接贴出官网下载的链接。最后记得添加到环境变量(其实只要安装时把"添加到PATH环境"选项勾起就可以了)。

  • Ruby version 1.9.3 or later
  • Perl version 5.12 or later
  • Python version 2.7.5 or later
  • JOM

建议安装jom,来替换nmake进行编译,可以充分利用CPU多核的能力,否则估计你会中途吐血的。
jom是nmake的多线程版,nmake不支持多线程(编译速度快很多)。

4、编译源码库

以上东西都准备好以后,接下来我们可以开始编译源码了。

  1. 在编译之前记得先将所有的杀毒软件关掉(避免误杀)。

  2. 然后进入解压后的Qt源码文件夹下的qtbase/mkspecs下,找到win32-msvc文件夹。Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第2张图片

  3. 进入选中的文件夹之后,找到qmake.conf文件并使用文本编辑器打开。

  4. 我们再根据它include的内容定位到相应的文件。

    include(../common/msvc-desktop.conf)
    
  5. 找到相应的文件后,修改其内容。在这里也就是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。

  6. 在开始菜单中,找到“适用于 VS 2017 的 x64 本机工具命令提示“ 或者 “x64 Native Tools Command Prompt for VS 2017”。
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第3张图片

  7. 将当前目录切换到源码解压后的目录下。比如我的是在E盘下的qt-everywhere-src-5.11.2这个文件夹。
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第4张图片

  8. 接下来,将执行关键的几个命令。首先执行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选项设置主机平台和用于构建Qt源码的编译器(对于Windows机器,可以使用MinGW或Visual Studio工具链来编译Qt)

    configure.bat -platform win32-g++
    configure.bat -platform win32-msvc

    · -static 选项表示编译静态库;
    . -debug-and-release 当然如果你只需要release版本,此选项可以改成"-release"
    · -prefix 该选项是用于指定编译完后的安装目录,此目录不需要事先创建,建议路径不要太长。
    . -qt 指定编译一些第三方库。
    这个过程不需要很久,执行完结果如图:
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第5张图片

  9. 执行jom命令。(这时候可以先去喝杯咖啡或者做做其他事情~~ )

  10. jom执行完毕之后,最后再输入jom install安装。 如果没有意外,那么我们就会在之前设定好的路径下看到编译好的文件。
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第6张图片
    至此,整个Qt源码编译过程也就结束了(过程说简单也简单,但我却搞了两三天,就因为前面环境没搭好
    但别高兴得太早,这还没结束呢。。我们必须得建立一个测试程序运行起来才算成功!

4、安装和配置

  1. VS2017中Qt插件安装教程

  2. 点击菜单栏上的“Qt VS Tools > Qt Options”打开Qt选项窗口;
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第7张图片

  3. 然后将我们编译好的Qt版本(E:\Qt5.11.2\Qt-msvc2017-x64-static)添加进来。
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第8张图片

  4. 我们创建一个Qt应用程序进行测试。
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第9张图片

5、整理下遇到的一些问题

  1. 问题一:使用Release方式编译,编译不通过!

    Qt5Core.lib(qobject.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”(main.obj 中)

    原因及解决方法:

    因为我们编译的Qt5.11.2的VC运行库是MT和MTd,工程向导创建的缺省是MD和MDd。也就是我们需要把运行库对应的值改了。
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第10张图片



  2. 问题二:

    LINK : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library

    原因及解决方法:

    在同一个项目中,所有的源文件必须链接相同的VC运行时库。如果某一文件用了MTd版本,而其他文件用MT版本的库,也就是说用了不同的库,就会导致这个警告的出现。 添加一下命令行可解决: Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第11张图片
    /NODEFAULTLIB:“libcmt.lib”



  3. 问题三:

    Qt5Core.lib(qglobal.obj) : error LNK2019: 无法解析的外部符号 gethostname,该符号在函数 “public: static class QString __cdecl QSysInfo::machineHostName(void)” (?machineHostName@QSysInfo@@SA?AVQString@@XZ) 中被引用
    Qt5Core.lib(qglobal.obj) : error LNK2019: 无法解析的外部符号 WSAStartup,该符号在函数 “public: __cdecl QWindowsSockInit::QWindowsSockInit(void)” (??0QWindowsSockInit@@QEAA@XZ) 中被引用
    Qt5Core.lib(qglobal.obj) : error LNK2019: 无法解析的外部符号 WSACleanup,该符号在函数 “public: __cdecl QWindowsSockInit::~QWindowsSockInit(void)” (??1QWindowsSockInit@@QEAA@XZ) 中被引用

    原因及解决方法:
    显然,这是因为有些依赖库我们没添加好!因此只要把必要的一些依赖文件添加进来一般都是能够解决!

    • 附加库目录改成:$(QTDIR)\lib; $(QTDIR)\plugins\imageformats; $(QTDIR)\plugins\platforms;%(AdditionalLibraryDirectories) Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第12张图片
    • 附加依赖项改成:Qt5AccessibilitySupport.lib;Qt5Network.lib;qtpcre2.lib;qtmain.lib;qwindows.lib;Qt5Widgets.lib;Qt5Core.lib;Qt5Gui.lib;Qt5PlatformCompositorSupport.lib;Qt5EventDispatcherSupport.lib;Qt5FontDatabaseSupport.lib;Qt5ThemeSupport.lib;Qt5WindowsUIAutomationSupport.lib;qgif.lib;qico.lib;qjpeg.lib;qtfreetype.lib;qtharfbuzz.lib;qtlibpng.lib;%(AdditionalDependencies)
      Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第13张图片
    • 在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")
      	#pragma comment(lib, "wtsapi32.lib")
      	#pragma comment(lib, "Wsock32.lib") 
      	#pragma comment(lib, "Imm32.lib") 
      	#pragma comment(lib, "Winmm.lib") 
      	#pragma comment(lib, "ws2_32.lib") 
      

    距离成功我们又进一步了,继续编译。。(如果依然会报类似的错误提示,可以自行尝试继续添加其他一些必要的依赖文件试试!)



  4. 问题四:
    Qt5.11.2 & VS2017 & 64位版本静态编译及使用_第14张图片

    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 
    	Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
    ```
    

    继续执行,发现可以了~ 成功了!
    在这里插入图片描述

你可能感兴趣的:(Qt5.11.2 & VS2017 & 64位版本静态编译及使用)