如何在VS2012下静态构建Qt 4.8/5.2,使用静态MSVC运行时,支持Windows XP?

Posted

技术标签:

【中文标题】如何在VS2012下静态构建Qt 4.8/5.2,使用静态MSVC运行时,支持Windows XP?【英文标题】:How to build Qt 4.8/5.2 statically under VS2012, using the static MSVC runtime, with Windows XP support? 【发布时间】:2014-02-18 19:03:15 【问题描述】:

我想在 VS2012 下创建一个完全静态的 Qt 4.8/5.2 构建 - 包括静态运行时库,并针对 Windows XP 系统。 Qt 不支持开箱即用,因为即使是 Qt 的静态构建也使用动态链接的 MSVC 运行时。

这是一个规范问题,提供成功构建满足这些要求的 Qt 所需的知识。

【问题讨论】:

嗨,你把我的问题作为重复的问题结束似乎有点奇怪,而事实上我的问题比你的问题早了 3 年。如果有什么你应该关闭你的。 @this.lau_ 这不是谁第一个的问题 :) 您编写自己的(重复的)问题,编写自己的答案,然后解决之前的问题。这里有点利益冲突,不是吗? 【参考方案1】:

Qt 5.2

假设环境已为 XP 定位做好准备,并且相关的 XP 定位 qt5xp.patch 和错误修复 qt5fixes.patch 可用 - 均来自 my other answer,我们必须执行以下操作:

    通过分别从qtbase/mkspecs/win32-msvc2012qtbase/mkspecs/win32-msvc2012-xp 复制它们来创建单独的win32-msvc2012-staticwin32-msvc2012-static-xp qmake 规范。

    修改 qmake 规范。

    向 configure 和 qmake makefile 介绍新的 qmake 规范。

    通过在qtbase 中创建一个空的.gitignore 文件来强制引导configure.exe

    如果您使用-prefix 配置Qt 以便安装和构建目录是分开的,您必须为QTBUG-32519 应用补丁 - 至少在该错误得到修复之前。

以下批处理文件完成了整个工作。目前,静态 Qt 构建禁用 webkit 构建。

:: Assume that we're in an equivalent of C:\Qt prefix
@set PREFIX=%~dp0
:: Qt sources
@set QT=%PREFIX%..\5.2.1-src
:: Patch file(s)
@set SRC=%PREFIX%
@set SPEC=win32-msvc2012
@if not exist "%QT%\qt.pro" ( echo Qt source folder expected in %QT%>&2 & exit /b 1 )
::
@patch --forward --directory=%QT% -p0 --global-reject-file=%SRC%\qt5fixes.rej --input=%SRC%\qt5fixes.patch
::
@echo > %QT%\qtbase\.gitignore
@mkdir %QT%\qtbase\mkspecs\%SPEC%-xp
@copy %QT%\qtbase\mkspecs\%SPEC%\qplatformdefs.h %QT%\qtbase\mkspecs\%SPEC%-xp
@copy %QT%\qtbase\mkspecs\%SPEC%\qmake.conf %QT%\qtbase\mkspecs\%SPEC%-xp
@patch --forward --directory=%QT% -p0 --global-reject-file=%SRC%\qt5xp.rej --input=%SRC%\qt5xp.patch
::
@mkdir %QT%\qtbase\mkspecs\%SPEC%-static
@copy %QT%\qtbase\mkspecs\%SPEC%\qplatformdefs.h %QT%\qtbase\mkspecs\%SPEC%-static
@copy %QT%\qtbase\mkspecs\%SPEC%\qmake.conf %QT%\qtbase\mkspecs\%SPEC%-static
@mkdir %QT%\qtbase\mkspecs\%SPEC%-static-xp
@copy %QT%\qtbase\mkspecs\%SPEC%-xp\qplatformdefs.h %QT%\qtbase\mkspecs\%SPEC%-static-xp
@copy %QT%\qtbase\mkspecs\%SPEC%-xp\qmake.conf %QT%\qtbase\mkspecs\%SPEC%-static-xp
@patch --forward --directory=%QT% -p0 --global-reject-file=%SRC%\qt5static.rej --input=%SRC%\qt5static.patch

撤消对 Qt 源代码的更改,运行以下命令,变量设置如上:

@patch --reverse --directory=%QT% -p0 --global-reject-file=%SRC%\qt5static-unfix.rej --input=%SRC%\qt5static.patch
@del %QT%\qtbase\mkspecs\%SPEC%-static\qplatformdefs.h
@del %QT%\qtbase\mkspecs\%SPEC%-static\qmake.conf
@rmdir %QT%\qtbase\mkspecs\%SPEC%-static
@del %QT%\qtbase\mkspecs\%SPEC%-static-xp\qplatformdefs.h
@del %QT%\qtbase\mkspecs\%SPEC%-static-xp\qmake.conf
@rmdir %QT%\qtbase\mkspecs\%SPEC%-static-xp
::
@patch --reverse --directory=%QT% -p0 --global-reject-file=%SRC%\qt5xp-unfix.rej --input=%SRC%\qt5xp.patch
@del %QT%\qtbase\mkspecs\%SPEC%-xp\qplatformdefs.h
@del %QT%\qtbase\mkspecs\%SPEC%-xp\qmake.conf
@rmdir %QT%\qtbase\mkspecs\%SPEC%-xp
@del %QT%\qtbase\.gitignore
::
@patch --reverse --directory=%QT% -p0 --global-reject-file=%SRC%\qt5fixes-unfix.rej --input=%SRC%\qt5fixes.patch

然后通过执行来执行构建

configure -static -platform win32-msvc2012-static-xp (or win32-msvc2012-static)
jom (or nmake)
jom install (if doing the build separate from the installation directory)
# qt5static.patch
# Static MSVC Runtime Support for Qt 5.2
#
# Build qmake with XP targeting.
--- qtbase/qmake/Makefile.win32 2014-02-20 12:28:23.316380600 -0500
+++ qtbase/qmake/Makefile.win32 2014-02-20 12:29:07.396008900 -0500
@@ -42,7 +42,7 @@
               -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
               -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
               -DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY
-!if "$(QMAKESPEC)" == "win32-msvc2012-xp"
+!if "$(QMAKESPEC)" == "win32-msvc2012-xp" || "$(QMAKESPEC)" == "win32-msvc2012-static-xp"
 CFLAGS_BARE = $(CFLAGS_BARE) -D_USING_V110_SDK71_
 !endif
 CFLAGS   = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS) $(EXTRA_CPPFLAGS)
# Add support for static qmake specs.
--- qtbase/qmake/Makefile.win32 2014-02-01 22:37:30.000000000 -0500
+++ qtbase/qmake/Makefile.win32 2014-02-17 16:21:09.329949100 -0500
@@ -1,4 +1,4 @@
-!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2012-xp" || "$(QMAKESPEC)" == "win32-msvc2013" || "$(QMAKESPEC)" == "win32-icc"
+!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2012-static" || "$(QMAKESPEC)" == "win32-msvc2012-static-xp" || "$(QMAKESPEC)" == "win32-msvc2012-xp" || "$(QMAKESPEC)" == "win32-msvc2013" || "$(QMAKESPEC)" == "win32-icc"
 
 !if "$(SOURCE_PATH)" == ""
 SOURCE_PATH = ..

# Set static runtime.
--- qtbase/mkspecs/win32-msvc2012-static/qmake.conf 2014-02-17 23:01:29.965440300 -0500
+++ qtbase/mkspecs/win32-msvc2012-static/qmake.conf 2014-02-17 23:05:51.630568400 -0500
@@ -24,9 +24,9 @@
 QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t
 QMAKE_CFLAGS_WARN_ON    = -W3
 QMAKE_CFLAGS_WARN_OFF   = -W0
-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 -d2Zi+
+QMAKE_CFLAGS_DEBUG      = -Zi -MTd -d2Zi+
 QMAKE_CFLAGS_YACC       =
 QMAKE_CFLAGS_LTCG       = -GL
 QMAKE_CFLAGS_MP         = -MP
# Set static runtime.
--- qtbase/mkspecs/win32-msvc2012-static-xp/qmake.conf  2014-02-17 23:01:29.965440300 -0500
+++ qtbase/mkspecs/win32-msvc2012-static-xp/qmake.conf  2014-02-17 23:05:51.630568400 -0500
@@ -24,9 +24,9 @@
 QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t
 QMAKE_CFLAGS_WARN_ON    = -W3
 QMAKE_CFLAGS_WARN_OFF   = -W0
-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 -d2Zi+
+QMAKE_CFLAGS_DEBUG      = -Zi -MTd -d2Zi+
 QMAKE_CFLAGS_YACC       =
 QMAKE_CFLAGS_LTCG       = -GL
 QMAKE_CFLAGS_MP         = -MP

【讨论】:

【参考方案2】:

Qt 4.8

假设环境已为 XP 定位做好准备,并且相关的 XP 定位 qt4xp.patch 和错误修复 qt4fixes.patch 可用 - 均来自 my other answer,则以下脚本可以完成这项工作:

:: Assume that we're in an equivalent of C:\Qt prefix
@set PREFIX=%~dp0
:: Qt sources
@set QT=%PREFIX%..\4.8.5-src
:: Patch file(s)
@set SRC=%PREFIX%
@set SPEC=win32-msvc2012
@if not exist "%QT%\projects.pro" ( echo Qt source folder expected in %QT%>&2 & exit /b 1 )
::
@patch --forward --directory=%QT% -p0 --global-reject-file=%SRC%\qt4fixes.rej --input=%SRC%\qt4fixes.patch
::
@mkdir %QT%\mkspecs\%SPEC%-xp
@copy %QT%\mkspecs\%SPEC%\qplatformdefs.h %QT%\mkspecs\%SPEC%-xp
@copy %QT%\mkspecs\%SPEC%\qmake.conf %QT%\mkspecs\%SPEC%-xp
@patch --forward --directory=%QT% -p0 --global-reject-file=%SRC%\qt4xp.rej --input=%SRC%\qt4xp.patch
::
@mkdir %QT%\mkspecs\%SPEC%-static
@copy %QT%\mkspecs\%SPEC%\qplatformdefs.h %QT%\mkspecs\%SPEC%-static
@copy %QT%\mkspecs\%SPEC%\qmake.conf %QT%\mkspecs\%SPEC%-static
@mkdir %QT%\mkspecs\%SPEC%-static-xp
@copy %QT%\mkspecs\%SPEC%-xp\qplatformdefs.h %QT%\mkspecs\%SPEC%-static-xp
@copy %QT%\mkspecs\%SPEC%-xp\qmake.conf %QT%\mkspecs\%SPEC%-static-xp
@patch --forward --directory=%QT% -p0 --global-reject-file=%SRC%\qt4static.rej --input=%SRC%\qt4static.patch

撤消对 Qt 源代码的更改,运行以下命令,变量设置如上:

@patch --reverse --directory=%QT% -p0 --global-reject-file=%SRC%\qt4static-unfix.rej --input=%SRC%\qt4static.patch
@del %QT%\mkspecs\%SPEC%-static\qplatformdefs.h
@del %QT%\mkspecs\%SPEC%-static\qmake.conf
@rmdir %QT%\mkspecs\%SPEC%-static
@del %QT%\mkspecs\%SPEC%-static-xp\qplatformdefs.h
@del %QT%\mkspecs\%SPEC%-static-xp\qmake.conf
@rmdir %QT%\mkspecs\%SPEC%-static-xp
::
@patch --reverse --directory=%QT% -p0 --global-reject-file=%SRC%\qt4xp-unfix.rej --input=%SRC%\qt4xp.patch
@del %QT%\mkspecs\%SPEC%-xp\qplatformdefs.h
@del %QT%\mkspecs\%SPEC%-xp\qmake.conf
@rmdir %QT%\mkspecs\%SPEC%-xp
::
@patch --reverse --directory=%QT% -p0 --global-reject-file=%SRC%\qt4fixes-unfix.rej --input=%SRC%\qt4fixes.patch

然后通过执行来执行构建

configure -static -platform win32-msvc2012-static-xp (or win32-msvc2012-static)
jom (or nmake)
# qt4static.patch
# Static MSVC Runtime Support for Qt 4.8
#
# Build configure with XP targeting
--- tools/configure/configure.pro   2014-02-20 10:00:29.840317000 -0500
+++ tools/configure/configure.pro   2014-02-20 10:03:06.674999600 -0500
@@ -4,7 +4,7 @@
 CONFIG   += console flat stl rtti_off
 CONFIG   -= moc qt
 DEFINES  = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_NO_THREAD QT_NO_QOBJECT QT_NO_GEOM_VARIANT _CRT_SECURE_NO_DEPRECATE
-win32-msvc2012-xp: DEFINES += _USING_V110_SDK71_
+win32-msvc2012-xp|win32-msvc2012-static-xp: DEFINES += _USING_V110_SDK71_
 DEFINES  += QT_BOOTSTRAPPED
 
 win32 : LIBS += -lole32 -ladvapi32
# Add support for static qmake specs.
--- qmake/Makefile.win32    2013-06-07 09:17:02.000000000 -0400
+++ qmake/Makefile.win32    2014-02-20 09:31:51.090426700 -0500
@@ -1,4 +1,4 @@
-!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2012-xp" || "$(QMAKESPEC)" == "win32-icc"
+!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2012-xp" || "$(QMAKESPEC)" == "win32-msvc2012-static" || "$(QMAKESPEC)" == "win32-msvc2012-static-xp" || "$(QMAKESPEC)" == "win32-icc"
 
 !if "$(SOURCE_PATH)" == ""
 SOURCE_PATH = ..
@@ -42,9 +42,9 @@
               -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \
               -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED \
               -DQLIBRARYINFO_EPOCROOT
-!if "$(QMAKESPEC)" == "win32-msvc2012-xp"
-CFLAGS_BARE = $(CFLAGS_BARE) -D_USING_V110_SDK71_
-!endif
+!if "$(QMAKESPEC)" == "win32-msvc2012-xp" || "$(QMAKESPEC)" == "win32-msvc2012-static-xp"
+CFLAGS_BARE = $(CFLAGS_BARE) -D_USING_V110_SDK71_
+!endif
 CFLAGS   = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS)
 
 CXXFLAGS_BARE = $(CFLAGS_BARE)
# Set static runtime
--- mkspecs/win32-msvc2012-static/qmake.conf    2013-06-07 09:17:00.000000000 -0400
+++ mkspecs/win32-msvc2012-static/qmake.conf    2014-02-17 16:17:38.831119700 -0500
@@ -19,9 +19,9 @@
 QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t-
 QMAKE_CFLAGS_WARN_ON    = -W3
 QMAKE_CFLAGS_WARN_OFF   = -W0
-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 -d2Zi+
+QMAKE_CFLAGS_DEBUG      = -Zi -MTd -d2Zi+
 QMAKE_CFLAGS_YACC       =
 QMAKE_CFLAGS_LTCG       = -GL
 QMAKE_CFLAGS_MP         = -MP
# Set static runtime
--- mkspecs/win32-msvc2012-static-xp/qmake.conf 2013-06-07 09:17:00.000000000 -0400
+++ mkspecs/win32-msvc2012-static-xp/qmake.conf 2014-02-17 16:17:38.831119700 -0500
@@ -19,9 +19,9 @@
 QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t-
 QMAKE_CFLAGS_WARN_ON    = -W3
 QMAKE_CFLAGS_WARN_OFF   = -W0
-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 -d2Zi+
+QMAKE_CFLAGS_DEBUG      = -Zi -MTd -d2Zi+
 QMAKE_CFLAGS_YACC       =
 QMAKE_CFLAGS_LTCG       = -GL
 QMAKE_CFLAGS_MP         = -MP

【讨论】:

以上是关于如何在VS2012下静态构建Qt 4.8/5.2,使用静态MSVC运行时,支持Windows XP?的主要内容,如果未能解决你的问题,请参考以下文章

如何在VS2015中使用PostgreSQL插件静态编译Qt 5.8

如何使用VS2012调试QT程序

Qt .pro 转换为 nmake Makefiles 无法处理静态库,在 VS2008 解决方案中同样有效

Win7下不能用VS2015构建Qt 5.6?

QT 静态编译

怎样VS2013下安装Qt5的插件