summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2014-04-02 16:56:15 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-03 18:31:45 +0200
commit10a0ac759e26e27751ae96d02eb1e260ab371194 (patch)
tree2915a74edeae37664c057af4fa9ed7c2aa5a6652
parentf412f2b5ee58e3919a8cd514c8fcfa75444ae976 (diff)
Windows XP target support for MSVC >= 2012
To enable windows xp support, we must do two things: 1. linker flag must be /SUBSYSTEM:CONSOLE,5.01 or /SUBSYSTEM:WINDOWS,5.01. For x64, the version is 5.02. 2. Do not use Windows Kit 8. Win SDK v7.1A is recommended. Prepend the right include paths and lib paths to INCLUDE and LIB before building. The Windows XP target support is enabled by passing "-target xp" to configure. Task-number: QTBUG-29939 Change-Id: I84c8439606cc2a9d27d64947702846faa4f1e4a2 Reviewed-by: Lucas Wang <wbsecg1@gmail.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
-rw-r--r--mkspecs/features/win32/console.prf4
-rw-r--r--mkspecs/features/win32/qt_config.prf10
-rw-r--r--mkspecs/features/win32/windows.prf4
-rw-r--r--mkspecs/win32-msvc2012/qmake.conf4
-rw-r--r--mkspecs/win32-msvc2013/qmake.conf4
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp10
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp4
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp4
-rw-r--r--tools/configure/configureapp.cpp29
9 files changed, 60 insertions, 13 deletions
diff --git a/mkspecs/features/win32/console.prf b/mkspecs/features/win32/console.prf
index 8a1725d648..568d1b1eb5 100644
--- a/mkspecs/features/win32/console.prf
+++ b/mkspecs/features/win32/console.prf
@@ -1,4 +1,6 @@
CONFIG -= windows
contains(TEMPLATE, ".*app") {
- QMAKE_LFLAGS += $$QMAKE_LFLAGS_CONSOLE $$QMAKE_LFLAGS_EXE
+ QMAKE_LFLAGS += \
+ $$replace(QMAKE_LFLAGS_CONSOLE, @QMAKE_SUBSYSTEM_SUFFIX@, $$QMAKE_SUBSYSTEM_SUFFIX) \
+ $$QMAKE_LFLAGS_EXE
}
diff --git a/mkspecs/features/win32/qt_config.prf b/mkspecs/features/win32/qt_config.prf
new file mode 100644
index 0000000000..49b4c79431
--- /dev/null
+++ b/mkspecs/features/win32/qt_config.prf
@@ -0,0 +1,10 @@
+load(qt_config)
+
+equals(QMAKE_TARGET_OS, xp) {
+ # http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx?PageIndex=3
+ equals(QT_ARCH, x86_64) {
+ QMAKE_SUBSYSTEM_SUFFIX = ,5.02
+ } else {
+ QMAKE_SUBSYSTEM_SUFFIX = ,5.01
+ }
+}
diff --git a/mkspecs/features/win32/windows.prf b/mkspecs/features/win32/windows.prf
index 82e0ebe1b5..6d8289d949 100644
--- a/mkspecs/features/win32/windows.prf
+++ b/mkspecs/features/win32/windows.prf
@@ -1,6 +1,8 @@
CONFIG -= console
contains(TEMPLATE, ".*app"){
- QMAKE_LFLAGS += $$QMAKE_LFLAGS_WINDOWS $$QMAKE_LFLAGS_EXE
+ QMAKE_LFLAGS += \
+ $$replace(QMAKE_LFLAGS_WINDOWS, @QMAKE_SUBSYSTEM_SUFFIX@, $$QMAKE_SUBSYSTEM_SUFFIX) \
+ $$QMAKE_LFLAGS_EXE
mingw:DEFINES += QT_NEEDS_QMAIN
qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) {
diff --git a/mkspecs/win32-msvc2012/qmake.conf b/mkspecs/win32-msvc2012/qmake.conf
index 18ffc27711..2cedc46807 100644
--- a/mkspecs/win32-msvc2012/qmake.conf
+++ b/mkspecs/win32-msvc2012/qmake.conf
@@ -70,8 +70,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
QMAKE_LFLAGS_DEBUG = /DEBUG
-QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
-QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
QMAKE_LFLAGS_DLL = /DLL
QMAKE_LFLAGS_LTCG = /LTCG
diff --git a/mkspecs/win32-msvc2013/qmake.conf b/mkspecs/win32-msvc2013/qmake.conf
index ad46a2fb72..6e0bd0b214 100644
--- a/mkspecs/win32-msvc2013/qmake.conf
+++ b/mkspecs/win32-msvc2013/qmake.conf
@@ -70,8 +70,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
QMAKE_LFLAGS_DEBUG = /DEBUG
-QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
-QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
QMAKE_LFLAGS_DLL = /DLL
QMAKE_LFLAGS_LTCG = /LTCG
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 86a9d518f2..03a41fd1bc 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -396,12 +396,18 @@ QString VcprojGenerator::retrievePlatformToolSet() const
if (!envVar.isEmpty())
return envVar;
+ QString suffix;
+ if (vcProject.Configuration.WinPhone)
+ suffix = "_wp80";
+ else if (project->first("QMAKE_TARGET_OS") == "xp")
+ suffix = "_xp";
+
switch (vcProject.Configuration.CompilerVersion)
{
case NET2012:
- return vcProject.Configuration.WinPhone ? "v110_wp80" : "v110";
+ return QStringLiteral("v110") + suffix;
case NET2013:
- return "v120";
+ return QStringLiteral("v120") + suffix;
default:
return QString();
}
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 7741eb4c1e..8e3bacd6b7 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -606,7 +606,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
// FILE_INFO_BY_HANDLE_CLASS has been extended by FileIdInfo = 18 as of VS2012.
typedef enum { Q_FileIdInfo = 18 } Q_FILE_INFO_BY_HANDLE_CLASS;
-# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700)
+# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && (_MSC_VER < 1700 || WINVER <= 0x0601))
// MinGW-64 defines FILE_ID_128 as of gcc-4.8.1 along with FILE_SUPPORTS_INTEGRITY_STREAMS
# if !(defined(Q_CC_MINGW) && defined(FILE_SUPPORTS_INTEGRITY_STREAMS))
@@ -619,7 +619,7 @@ typedef struct _FILE_ID_INFO {
ULONGLONG VolumeSerialNumber;
FILE_ID_128 FileId;
} FILE_ID_INFO, *PFILE_ID_INFO;
-# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700))
+# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && (_MSC_VER < 1700 || WINVER <= 0x0601))
// File ID for Windows up to version 7.
static inline QByteArray fileId(HANDLE handle)
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index dfb897c0fd..64ad2ff0d3 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -435,10 +435,10 @@ static inline UINT inputTimerMask()
UINT result = QS_TIMER | QS_INPUT | QS_RAWINPUT;
// QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
// QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
-#if defined(_MSC_VER) && _MSC_VER >= 1700
+#if WINVER > 0x0601
if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8)
result &= ~(QS_TOUCH | QS_POINTER);
-#endif // _MSC_VER >= 1700
+#endif // WINVER > 0x0601
return result;
}
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 176fe3092f..49c7fc9618 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -482,7 +482,18 @@ void Configure::parseCmdLine()
else if (configCmdLine.at(i) == "-force-asserts") {
dictionary[ "FORCE_ASSERTS" ] = "yes";
}
-
+ else if (configCmdLine.at(i) == "-target") {
+ ++i;
+ if (i == argCount)
+ break;
+ const QString option = configCmdLine.at(i);
+ if (option != "xp") {
+ cout << "ERROR: invalid argument for -target option" << endl;
+ dictionary["DONE"] = "error";
+ return;
+ }
+ dictionary["TARGET_OS"] = option;
+ }
else if (configCmdLine.at(i) == "-platform") {
++i;
if (i == argCount)
@@ -1817,6 +1828,10 @@ bool Configure::displayHelp()
desc( "-platform <spec>", "The operating system and compiler you are building on.\n(default %QMAKESPEC%)\n");
desc( "-xplatform <spec>", "The operating system and compiler you are cross compiling to.\n");
desc( "", "See the README file for a list of supported operating systems and compilers.\n", false, ' ');
+
+ desc("TARGET_OS", "*", "-target", "Set target OS version. Currently the only valid value is 'xp' for targeting Windows XP.\n"
+ "MSVC >= 2012 targets Windows Vista by default.\n");
+
desc( "-sysroot <dir>", "Sets <dir> as the target compiler's and qmake's sysroot and also sets pkg-config paths.");
desc( "-no-gcc-sysroot", "When using -sysroot, it disables the passing of --sysroot to the compiler.\n");
@@ -2497,6 +2512,12 @@ bool Configure::verifyConfiguration()
<< "files such as headers and libraries." << endl;
prompt = true;
}
+#if WINVER > 0x0601
+ if (dictionary["TARGET_OS"] == "xp") {
+ cout << "WARNING: Cannot use Windows Kit 8 to build Qt for Windows XP.\n"
+ "WARNING: Windows SDK v7.1A is recommended.\n";
+ }
+#endif
if (dictionary["DIRECT2D"] == "yes" && !checkAvailability("DIRECT2D")) {
cout << "WARNING: To be able to build the Direct2D platform plugin you will" << endl
@@ -3331,6 +3352,10 @@ void Configure::generateQConfigPri()
<< "}" << endl;
}
+ const QString targetOS = dictionary.value("TARGET_OS");
+ if (!targetOS.isEmpty())
+ configStream << "QMAKE_TARGET_OS = " << targetOS << endl;
+
if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
configStream << "QMAKE_RPATHDIR += " << formatPath(dictionary["QMAKE_RPATHDIR"]) << endl;
@@ -3574,6 +3599,8 @@ void Configure::displayConfig()
sout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
else
sout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
+ if (!dictionary["TARGET_OS"].isEmpty())
+ sout << "Target OS..................." << dictionary["TARGET_OS"] << endl;
sout << "Architecture................" << dictionary["QT_ARCH"]
<< ", features:" << dictionary["QT_CPU_FEATURES"] << endl;
sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"]