Remove wondrous VS version detection logic

Replace which_dotnet_version with a simple function that converts the
value of MSVC_VER to its corresponding enum value in the VS project
generator.
This reduces the maintenance burden when adding support for a new VS
version, because we do not need to update the registry keys in
which_dotnet_version anymore.
The which_dotnet_version function implemented the following logic:
  - find all installed VS versions via registry
  - select the "best matching one"
  - if there is no best match, select the VS that's in PATH
  - create a project for that VS installation
The usefulness of this whole stunt is questionable as the VS version of
Qt's mkspec must match the version of a project using that Qt anyway.

Change-Id: I9fb9a099ee5ddb5fc4c450be4f68f41f2b406b9a
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Joerg Bornemann 2016-11-10 09:40:09 +01:00
parent a3c9550d7c
commit 2713f080bb
3 changed files with 33 additions and 92 deletions

View File

@ -34,6 +34,36 @@
QT_BEGIN_NAMESPACE
static DotNET vsVersionFromString(const char *versionString)
{
struct VSVersionMapping
{
const char *str;
DotNET version;
};
static VSVersionMapping mapping[] = {
"7.0", NET2002,
"7.1", NET2003,
"8.0", NET2005,
"9.0", NET2008,
"10.0", NET2010,
"11.0", NET2012,
"12.0", NET2013,
"14.0", NET2015
};
DotNET result = NETUnknown;
for (const auto entry : mapping) {
if (strcmp(entry.str, versionString) == 0)
return entry.version;
}
return result;
}
DotNET vsVersionFromString(const ProString &versionString)
{
return vsVersionFromString(versionString.toLatin1().constData());
}
// XML Tags ---------------------------------------------------------
const char _Configuration[] = "Configuration";
const char _Configurations[] = "Configurations";

View File

@ -54,6 +54,8 @@ enum DotNET {
NET2015 = 0xd0
};
DotNET vsVersionFromString(const ProString &versionString);
/*
This Object model is of course VERY simplyfied,
and does not actually follow the original MSVC

View File

@ -50,97 +50,6 @@ const char _GUIDFormFiles[] = "{99349809-55BA-4b9d-BF79-8FDBB0286EB3}
const char _GUIDExtraCompilerFiles[] = "{E0D8C965-CC5F-43d7-AD63-FAEF0BBC0F85}";
const char _GUIDDeploymentFiles[] = "{D9D6E243-F8AF-46E4-B9FD-80ECBC20BA3E}";
const char _GUIDDistributionFiles[] = "{B83CAF91-C7BF-462F-B76C-EA11631F866C}";
QT_END_NAMESPACE
#ifdef Q_OS_WIN32
#include <qt_windows.h>
#include <windows/registry_p.h>
QT_BEGIN_NAMESPACE
struct DotNetCombo {
DotNET version;
const char *versionStr;
const char *regKey;
} dotNetCombo[] = {
{NET2015, "MSVC.NET 2015 (14.0)", "Software\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"},
{NET2013, "MSVC.NET 2013 (12.0)", "Software\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"},
{NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"},
{NET2012, "MSVC.NET 2012 (11.0)", "Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"},
{NET2012, "MSVC.NET 2012 Express Edition (11.0)", "Software\\Microsoft\\VCExpress\\11.0\\Setup\\VC\\ProductDir"},
{NET2010, "MSVC.NET 2010 (10.0)", "Software\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir"},
{NET2010, "MSVC.NET 2010 Express Edition (10.0)", "Software\\Microsoft\\VCExpress\\10.0\\Setup\\VC\\ProductDir"},
{NET2008, "MSVC.NET 2008 (9.0)", "Software\\Microsoft\\VisualStudio\\9.0\\Setup\\VC\\ProductDir"},
{NET2008, "MSVC.NET 2008 Express Edition (9.0)", "Software\\Microsoft\\VCExpress\\9.0\\Setup\\VC\\ProductDir"},
{NET2005, "MSVC.NET 2005 (8.0)", "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"},
{NET2005, "MSVC.NET 2005 Express Edition (8.0)", "Software\\Microsoft\\VCExpress\\8.0\\Setup\\VC\\ProductDir"},
{NET2003, "MSVC.NET 2003 (7.1)", "Software\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"},
{NET2002, "MSVC.NET 2002 (7.0)", "Software\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"},
{NETUnknown, "", ""},
};
QT_END_NAMESPACE
#endif
QT_BEGIN_NAMESPACE
DotNET which_dotnet_version(const QByteArray &preferredVersion = QByteArray())
{
#ifndef Q_OS_WIN32
Q_UNUSED(preferredVersion);
return NET2002; // Always generate 7.0 versions on other platforms
#else
// Only search for the version once
static DotNET current_version = NETUnknown;
if(current_version != NETUnknown)
return current_version;
// Fallback to .NET 2002
current_version = NET2002;
const DotNetCombo *lowestInstalledVersion = 0;
QHash<DotNET, QString> installPaths;
int installed = 0;
int i = 0;
for(; dotNetCombo[i].version; ++i) {
QString path = qt_readRegistryKey(HKEY_LOCAL_MACHINE, dotNetCombo[i].regKey,
KEY_WOW64_32KEY);
if (!path.isEmpty() && installPaths.value(dotNetCombo[i].version) != path) {
lowestInstalledVersion = &dotNetCombo[i];
installPaths.insert(lowestInstalledVersion->version, path);
++installed;
current_version = lowestInstalledVersion->version;
if (QByteArray(lowestInstalledVersion->versionStr).contains(preferredVersion)) {
installed = 1;
break;
}
}
}
if (installed < 2)
return current_version;
// More than one version installed, search directory path
QString paths = qgetenv("PATH");
const QStringList pathlist = paths.split(QLatin1Char(';'));
for (const QString &path : pathlist) {
for (i = 0; dotNetCombo[i].version; ++i) {
const QString productPath = installPaths.value(dotNetCombo[i].version);
if (productPath.isEmpty())
continue;
if (path.startsWith(productPath, Qt::CaseInsensitive)) {
current_version = dotNetCombo[i].version;
return current_version;
}
}
}
warn_msg(WarnLogic, "Generator: MSVC.NET: Found more than one version of Visual Studio, but"
" none in your PATH. Falling back to lowest version (%s)",
qPrintable(lowestInstalledVersion->versionStr));
return current_version;
#endif
};
// Flatfile Tags ----------------------------------------------------
const char _slnHeader70[] = "Microsoft Visual Studio Solution File, Format Version 7.00";
@ -986,7 +895,7 @@ void VcprojGenerator::initConfiguration()
// - to know of certain compiler/linker options
VCConfiguration &conf = vcProject.Configuration;
conf.suppressUnknownOptionWarnings = project->isActiveConfig("suppress_vcproj_warnings");
conf.CompilerVersion = which_dotnet_version(project->first("MSVC_VER").toLatin1());
conf.CompilerVersion = vsVersionFromString(project->first("MSVC_VER"));
if (conf.CompilerVersion >= NET2012) {
conf.WinRT = project->isActiveConfig("winrt");