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

我想在VS2012下完全构buildQt 4.8 / 5.2,包括静态运行时库,以及Windows XP系统。 Qt并不支持这个function,因为即使是Qt的静态构build也使用dynamic链接的MSVC运行时。

这是一个典型的问题,它提供了成功构build满足这些需求的Qt所必需的知识。

Qt 5.2

假设环境已经准备好用于XP定位,相关的XP定位qt5xp.patch和错误修复qt5fixes.patch可用 – 从我的其他答案 ,我们必须做到以下几点:

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

  2. 修改qmake规格。

  3. 教关于新的qmake规格的configuration和qmake makefile。

  4. 通过在qtbase创build一个空的.gitignore文件强制configure.exe的引导。

  5. 如果您使用-prefixconfigurationQt,以便安装目录和生成目录是分开的,那么您必须将修补程序应用于QTBUG-32519 – 至less在错误得到解决之前。

以下batch file执行完整的工作。 目前,对于静态Qt构build,webkit构build被禁用。

 :: 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源代码的更改,请运行以下代码,并设置如上所示的variables:

 @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 

然后通过执行构build

 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 

Qt 4.8

假设环境已经准备好用于XP定位,相关的XP定位qt4xp.patch和错误修复qt4fixes.patch可用 – 从我的其他答案 ,以下脚本执行的工作:

 :: 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源代码的更改,请运行以下代码,并设置如上所示的variables:

 @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 

然后通过执行构build

 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