PageRenderTime 62ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/plugins/projectexplorer/msvctoolchain.cpp

https://bitbucket.org/kyanha/qt-creator
C++ | 576 lines | 465 code | 55 blank | 56 comment | 71 complexity | bf07835cbb399c4a5cfcac24a62140b3 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
  4. ** Contact: http://www.qt-project.org/legal
  5. **
  6. ** This file is part of Qt Creator.
  7. **
  8. ** Commercial License Usage
  9. ** Licensees holding valid commercial Qt licenses may use this file in
  10. ** accordance with the commercial license agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Digia. For licensing terms and
  13. ** conditions see http://qt.digia.com/licensing. For further information
  14. ** use the contact form at http://qt.digia.com/contact-us.
  15. **
  16. ** GNU Lesser General Public License Usage
  17. ** Alternatively, this file may be used under the terms of the GNU Lesser
  18. ** General Public License version 2.1 as published by the Free Software
  19. ** Foundation and appearing in the file LICENSE.LGPL included in the
  20. ** packaging of this file. Please review the following information to
  21. ** ensure the GNU Lesser General Public License version 2.1 requirements
  22. ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  23. **
  24. ** In addition, as a special exception, Digia gives you certain additional
  25. ** rights. These rights are described in the Digia Qt LGPL Exception
  26. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  27. **
  28. ****************************************************************************/
  29. #include "msvctoolchain.h"
  30. #include "msvcparser.h"
  31. #include "projectexplorerconstants.h"
  32. #include "headerpath.h"
  33. #include <projectexplorer/projectexplorer.h>
  34. #include <projectexplorer/projectexplorersettings.h>
  35. #include <utils/fileutils.h>
  36. #include <utils/synchronousprocess.h>
  37. #include <utils/winutils.h>
  38. #include <utils/qtcassert.h>
  39. #include <QDir>
  40. #include <QFileInfo>
  41. #include <QProcess>
  42. #include <QSettings>
  43. #include <QUrl>
  44. #include <QFormLayout>
  45. #include <QDesktopServices>
  46. #define KEY_ROOT "ProjectExplorer.MsvcToolChain."
  47. static const char varsBatKeyC[] = KEY_ROOT"VarsBat";
  48. static const char varsBatArgKeyC[] = KEY_ROOT"VarsBatArg";
  49. static const char supportedAbiKeyC[] = KEY_ROOT"SupportedAbi";
  50. enum { debug = 0 };
  51. namespace ProjectExplorer {
  52. namespace Internal {
  53. // --------------------------------------------------------------------------
  54. // Helpers:
  55. // --------------------------------------------------------------------------
  56. static QString platformName(MsvcToolChain::Platform t)
  57. {
  58. switch (t) {
  59. case MsvcToolChain::x86:
  60. return QLatin1String(" (x86)");
  61. case MsvcToolChain::amd64:
  62. return QLatin1String(" (amd64)");
  63. case MsvcToolChain::x86_amd64:
  64. return QLatin1String(" (x86_amd64)");
  65. case MsvcToolChain::ia64:
  66. return QLatin1String(" (ia64)");
  67. case MsvcToolChain::x86_ia64:
  68. return QLatin1String(" (x86_ia64)");
  69. }
  70. return QString();
  71. }
  72. static Abi findAbiOfMsvc(MsvcToolChain::Type type, MsvcToolChain::Platform platform, const QString &version)
  73. {
  74. Abi::Architecture arch = Abi::X86Architecture;
  75. Abi::OSFlavor flavor = Abi::UnknownFlavor;
  76. int wordWidth = 64;
  77. switch (platform)
  78. {
  79. case ProjectExplorer::Internal::MsvcToolChain::x86:
  80. wordWidth = 32;
  81. break;
  82. case ProjectExplorer::Internal::MsvcToolChain::ia64:
  83. case ProjectExplorer::Internal::MsvcToolChain::x86_ia64:
  84. arch = Abi::ItaniumArchitecture;
  85. break;
  86. case ProjectExplorer::Internal::MsvcToolChain::amd64:
  87. case ProjectExplorer::Internal::MsvcToolChain::x86_amd64:
  88. break;
  89. };
  90. QString msvcVersionString = version;
  91. if (type == MsvcToolChain::WindowsSDK) {
  92. if (version.startsWith(QLatin1String("7.")))
  93. msvcVersionString = QLatin1String("10.0");
  94. else if (version.startsWith(QLatin1String("6.1"))
  95. || (version.startsWith(QLatin1String("6.0")) && version != QLatin1String("6.0")))
  96. // The 6.0 SDK is shipping MSVC2005, Starting at 6.0a it is MSVC2008.
  97. msvcVersionString = QLatin1String("9.0");
  98. else
  99. msvcVersionString = QLatin1String("8.0");
  100. }
  101. if (msvcVersionString.startsWith(QLatin1String("11.")))
  102. flavor = Abi::WindowsMsvc2012Flavor;
  103. else if (msvcVersionString.startsWith(QLatin1String("10.")))
  104. flavor = Abi::WindowsMsvc2010Flavor;
  105. else if (msvcVersionString.startsWith(QLatin1String("9.")))
  106. flavor = Abi::WindowsMsvc2008Flavor;
  107. else
  108. flavor = Abi::WindowsMsvc2005Flavor;
  109. const Abi result = Abi(arch, Abi::WindowsOS, flavor, Abi::PEFormat, wordWidth);
  110. if (!result.isValid())
  111. qWarning("Unable to completely determine the ABI of MSVC version %s (%s).",
  112. qPrintable(version), qPrintable(result.toString()));
  113. return result;
  114. }
  115. static QString generateDisplayName(const QString &name,
  116. MsvcToolChain::Type t,
  117. MsvcToolChain::Platform p)
  118. {
  119. if (t == MsvcToolChain::WindowsSDK) {
  120. QString sdkName = name;
  121. sdkName += platformName(p);
  122. return sdkName;
  123. }
  124. // Comes as "9.0" from the registry
  125. QString vcName = QLatin1String("Microsoft Visual C++ Compiler ");
  126. vcName += name;
  127. vcName += platformName(p);
  128. return vcName;
  129. }
  130. static QByteArray msvcCompilationFile()
  131. {
  132. static const char* macros[] = {"_ATL_VER", "_CHAR_UNSIGNED", "__CLR_VER",
  133. "__cplusplus_cli", "__COUNTER__", "__cplusplus",
  134. "_CPPLIB_VER", "_CPPRTTI", "_CPPUNWIND",
  135. "_DEBUG", "_DLL", "__FUNCDNAME__",
  136. "__FUNCSIG__", "__FUNCTION__", "_INTEGRAL_MAX_BITS",
  137. "_M_ALPHA", "_M_AAMD64", "_M_CEE", "_M_CEE_PURE",
  138. "_M_CEE_SAFE", "_M_IX86", "_M_IA64",
  139. "_M_IX86_FP", "_M_MPPC", "_M_MRX000",
  140. "_M_PPC", "_M_X64", "_MANAGED",
  141. "_MFC_VER", "_MSC_BUILD", "_MSC_EXTENSIONS",
  142. "_MSC_FULL_VER", "_MSC_VER", "__MSVC_RUNTIME_CHECKS",
  143. "_MT", "_NATIVE_WCHAR_T_DEFINED", "_OPENMP",
  144. "_VC_NODEFAULTLIB", "_WCHAR_T_DEFINED", "_WIN32",
  145. "_WIN32_WCE", "_WIN64", "_Wp64",
  146. "__DATE__", "__TIME__", "__TIMESTAMP__",
  147. 0};
  148. QByteArray file = "#define __PPOUT__(x) V##x=x\n\n";
  149. for (int i = 0; macros[i] != 0; ++i) {
  150. const QByteArray macro(macros[i]);
  151. file += "#if defined(" + macro + ")\n__PPOUT__("
  152. + macro + ")\n#endif\n";
  153. }
  154. file += "\nvoid main(){}\n\n";
  155. return file;
  156. }
  157. // Run MSVC 'cl' compiler to obtain #defines.
  158. QByteArray MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags,
  159. const Utils::Environment &env) const
  160. {
  161. QByteArray predefinedMacros = AbstractMsvcToolChain::msvcPredefinedMacros(cxxflags, env);
  162. QStringList toProcess;
  163. foreach (const QString &arg, cxxflags) {
  164. if (arg.startsWith(QLatin1String("/D"))) {
  165. QString define = arg.mid(2);
  166. int pos = define.indexOf(QLatin1Char('='));
  167. if (pos < 0) {
  168. predefinedMacros += "#define ";
  169. predefinedMacros += define.toLocal8Bit();
  170. predefinedMacros += '\n';
  171. } else {
  172. predefinedMacros += "#define ";
  173. predefinedMacros += define.left(pos).toLocal8Bit();
  174. predefinedMacros += ' ';
  175. predefinedMacros += define.mid(pos + 1).toLocal8Bit();
  176. predefinedMacros += '\n';
  177. }
  178. } else if (arg.startsWith(QLatin1String("/U"))) {
  179. predefinedMacros += "#undef ";
  180. predefinedMacros += arg.mid(2).toLocal8Bit();
  181. predefinedMacros += '\n';
  182. } else {
  183. toProcess.append(arg);
  184. }
  185. }
  186. Utils::TempFileSaver saver(QDir::tempPath() + QLatin1String("/envtestXXXXXX.cpp"));
  187. saver.write(msvcCompilationFile());
  188. if (!saver.finalize()) {
  189. qWarning("%s: %s", Q_FUNC_INFO, qPrintable(saver.errorString()));
  190. return predefinedMacros;
  191. }
  192. QProcess cpp;
  193. cpp.setEnvironment(env.toStringList());
  194. cpp.setWorkingDirectory(QDir::tempPath());
  195. QStringList arguments;
  196. const QString binary = env.searchInPath(QLatin1String("cl.exe"));
  197. if (binary.isEmpty()) {
  198. qWarning("%s: The compiler binary cl.exe could not be found in the path.", Q_FUNC_INFO);
  199. return predefinedMacros;
  200. }
  201. arguments << toProcess << QLatin1String("/EP") << QDir::toNativeSeparators(saver.fileName());
  202. cpp.start(binary, arguments);
  203. if (!cpp.waitForStarted()) {
  204. qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(binary),
  205. qPrintable(cpp.errorString()));
  206. return predefinedMacros;
  207. }
  208. cpp.closeWriteChannel();
  209. if (!cpp.waitForFinished()) {
  210. Utils::SynchronousProcess::stopProcess(cpp);
  211. qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(binary));
  212. return predefinedMacros;
  213. }
  214. if (cpp.exitStatus() != QProcess::NormalExit) {
  215. qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(binary));
  216. return predefinedMacros;
  217. }
  218. const QList<QByteArray> output = cpp.readAllStandardOutput().split('\n');
  219. foreach (const QByteArray& line, output) {
  220. if (line.startsWith('V')) {
  221. QList<QByteArray> split = line.split('=');
  222. const QByteArray key = split.at(0).mid(1);
  223. QByteArray value = split.at(1);
  224. if (!value.isEmpty())
  225. value.chop(1); //remove '\n'
  226. predefinedMacros += "#define ";
  227. predefinedMacros += key;
  228. predefinedMacros += ' ';
  229. predefinedMacros += value;
  230. predefinedMacros += '\n';
  231. }
  232. }
  233. if (debug)
  234. qDebug() << "msvcPredefinedMacros" << predefinedMacros;
  235. return predefinedMacros;
  236. }
  237. // Windows: Expand the delayed evaluation references returned by the
  238. // SDK setup scripts: "PATH=!Path!;foo". Some values might expand
  239. // to empty and should not be added
  240. static QString winExpandDelayedEnvReferences(QString in, const Utils::Environment &env)
  241. {
  242. const QChar exclamationMark = QLatin1Char('!');
  243. for (int pos = 0; pos < in.size(); ) {
  244. // Replace "!REF!" by its value in process environment
  245. pos = in.indexOf(exclamationMark, pos);
  246. if (pos == -1)
  247. break;
  248. const int nextPos = in.indexOf(exclamationMark, pos + 1);
  249. if (nextPos == -1)
  250. break;
  251. const QString var = in.mid(pos + 1, nextPos - pos - 1);
  252. const QString replacement = env.value(var.toUpper());
  253. in.replace(pos, nextPos + 1 - pos, replacement);
  254. pos += replacement.size();
  255. }
  256. return in;
  257. }
  258. Utils::Environment MsvcToolChain::readEnvironmentSetting(Utils::Environment& env) const
  259. {
  260. Utils::Environment result = env;
  261. if (!QFileInfo(m_vcvarsBat).exists())
  262. return result;
  263. QMap<QString, QString> envPairs;
  264. if (!generateEnvironmentSettings(env, m_vcvarsBat, m_varsBatArg, envPairs))
  265. return result;
  266. // Now loop through and process them
  267. QMap<QString,QString>::const_iterator envIter;
  268. for (envIter = envPairs.begin(); envIter!=envPairs.end(); ++envIter) {
  269. const QString expandedValue = winExpandDelayedEnvReferences(envIter.value(), env);
  270. if (!expandedValue.isEmpty())
  271. result.set(envIter.key(), expandedValue);
  272. }
  273. if (debug) {
  274. const QStringList newVars = result.toStringList();
  275. const QStringList oldVars = env.toStringList();
  276. QDebug nsp = qDebug().nospace();
  277. foreach (const QString &n, newVars) {
  278. if (!oldVars.contains(n))
  279. nsp << n << '\n';
  280. }
  281. }
  282. return result;
  283. }
  284. // --------------------------------------------------------------------------
  285. // MsvcToolChain
  286. // --------------------------------------------------------------------------
  287. MsvcToolChain::MsvcToolChain(const QString &name, const Abi &abi,
  288. const QString &varsBat, const QString &varsBatArg, bool autodetect) :
  289. AbstractMsvcToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), autodetect, abi, varsBat),
  290. m_varsBatArg(varsBatArg)
  291. {
  292. Q_ASSERT(!name.isEmpty());
  293. setDisplayName(name);
  294. }
  295. MsvcToolChain::MsvcToolChain() :
  296. AbstractMsvcToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), false)
  297. {
  298. }
  299. MsvcToolChain *MsvcToolChain::readFromMap(const QVariantMap &data)
  300. {
  301. MsvcToolChain *tc = new MsvcToolChain;
  302. if (tc->fromMap(data))
  303. return tc;
  304. delete tc;
  305. return 0;
  306. }
  307. QString MsvcToolChain::type() const
  308. {
  309. return QLatin1String("msvc");
  310. }
  311. QString MsvcToolChain::typeDisplayName() const
  312. {
  313. return MsvcToolChainFactory::tr("MSVC");
  314. }
  315. QList<Utils::FileName> MsvcToolChain::suggestedMkspecList() const
  316. {
  317. switch (m_abi.osFlavor()) {
  318. case ProjectExplorer::Abi::WindowsMsvc2005Flavor:
  319. return QList<Utils::FileName>() << Utils::FileName::fromString(QLatin1String("win32-msvc2005"));
  320. case ProjectExplorer::Abi::WindowsMsvc2008Flavor:
  321. return QList<Utils::FileName>() << Utils::FileName::fromString(QLatin1String("win32-msvc2008"));
  322. case ProjectExplorer::Abi::WindowsMsvc2010Flavor:
  323. return QList<Utils::FileName>() << Utils::FileName::fromString(QLatin1String("win32-msvc2010"));
  324. case ProjectExplorer::Abi::WindowsMsvc2012Flavor:
  325. QList<Utils::FileName>()
  326. << Utils::FileName::fromString(QLatin1String("win32-msvc2012"))
  327. << Utils::FileName::fromString(QLatin1String("win32-msvc2010"));
  328. break;
  329. default:
  330. break;
  331. }
  332. return QList<Utils::FileName>();
  333. }
  334. QVariantMap MsvcToolChain::toMap() const
  335. {
  336. QVariantMap data = ToolChain::toMap();
  337. data.insert(QLatin1String(varsBatKeyC), m_vcvarsBat);
  338. if (!m_varsBatArg.isEmpty())
  339. data.insert(QLatin1String(varsBatArgKeyC), m_varsBatArg);
  340. data.insert(QLatin1String(supportedAbiKeyC), m_abi.toString());
  341. return data;
  342. }
  343. bool MsvcToolChain::fromMap(const QVariantMap &data)
  344. {
  345. if (!ToolChain::fromMap(data))
  346. return false;
  347. m_vcvarsBat = data.value(QLatin1String(varsBatKeyC)).toString();
  348. m_varsBatArg = data.value(QLatin1String(varsBatArgKeyC)).toString();
  349. const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
  350. m_abi = Abi(abiString);
  351. return !m_vcvarsBat.isEmpty() && m_abi.isValid();
  352. }
  353. ToolChainConfigWidget *MsvcToolChain::configurationWidget()
  354. {
  355. return new MsvcToolChainConfigWidget(this);
  356. }
  357. ToolChain *MsvcToolChain::clone() const
  358. {
  359. return new MsvcToolChain(*this);
  360. }
  361. // --------------------------------------------------------------------------
  362. // MsvcToolChainConfigWidget
  363. // --------------------------------------------------------------------------
  364. MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) :
  365. ToolChainConfigWidget(tc),
  366. m_varsBatDisplayLabel(new QLabel(this))
  367. {
  368. m_mainLayout->addRow(new QLabel(tc->displayName()));
  369. m_varsBatDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
  370. m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayLabel);
  371. addErrorLabel();
  372. setFromToolChain();
  373. }
  374. void MsvcToolChainConfigWidget::setFromToolChain()
  375. {
  376. MsvcToolChain *tc = static_cast<MsvcToolChain *>(toolChain());
  377. QTC_ASSERT(tc, return);
  378. QString varsBatDisplay = tc->varsBat();
  379. if (!tc->varsBatArg().isEmpty()) {
  380. varsBatDisplay += QLatin1Char(' ');
  381. varsBatDisplay += tc->varsBatArg();
  382. }
  383. m_varsBatDisplayLabel->setText(varsBatDisplay);
  384. }
  385. // --------------------------------------------------------------------------
  386. // MsvcToolChainFactory
  387. // --------------------------------------------------------------------------
  388. QString MsvcToolChainFactory::displayName() const
  389. {
  390. return tr("MSVC");
  391. }
  392. QString MsvcToolChainFactory::id() const
  393. {
  394. return QLatin1String(Constants::MSVC_TOOLCHAIN_ID);
  395. }
  396. QList<ToolChain *> MsvcToolChainFactory::autoDetect()
  397. {
  398. QList<ToolChain *> results;
  399. // 1) Installed SDKs preferred over standalone Visual studio
  400. const QSettings sdkRegistry(QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows"),
  401. QSettings::NativeFormat);
  402. const QString defaultSdkPath = sdkRegistry.value(QLatin1String("CurrentInstallFolder")).toString();
  403. if (!defaultSdkPath.isEmpty()) {
  404. foreach (const QString &sdkKey, sdkRegistry.childGroups()) {
  405. const QString name = sdkRegistry.value(sdkKey + QLatin1String("/ProductName")).toString();
  406. const QString version = sdkRegistry.value(sdkKey + QLatin1String("/ProductVersion")).toString();
  407. const QString folder = sdkRegistry.value(sdkKey + QLatin1String("/InstallationFolder")).toString();
  408. if (folder.isEmpty())
  409. continue;
  410. QDir dir(folder);
  411. if (!dir.cd(QLatin1String("bin")))
  412. continue;
  413. QFileInfo fi(dir, QLatin1String("SetEnv.cmd"));
  414. if (!fi.exists())
  415. continue;
  416. QList<ToolChain *> tmp;
  417. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
  418. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, version),
  419. fi.absoluteFilePath(), QLatin1String("/x86"), true));
  420. // Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
  421. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
  422. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, version),
  423. fi.absoluteFilePath(), QLatin1String("/x64"), true));
  424. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64),
  425. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64, version),
  426. fi.absoluteFilePath(), QLatin1String("/x64"), true));
  427. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
  428. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, version),
  429. fi.absoluteFilePath(), QLatin1String("/ia64"), true));
  430. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64),
  431. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64, version),
  432. fi.absoluteFilePath(), QLatin1String("/ia64"), true));
  433. // Make sure the default is front.
  434. if (folder == defaultSdkPath)
  435. results = tmp + results;
  436. else
  437. results += tmp;
  438. } // foreach
  439. }
  440. // 2) Installed MSVCs
  441. const QSettings vsRegistry(
  442. #ifdef Q_OS_WIN64
  443. QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7"),
  444. #else
  445. QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7"),
  446. #endif
  447. QSettings::NativeFormat);
  448. foreach (const QString &vsName, vsRegistry.allKeys()) {
  449. // Scan for version major.minor
  450. const int dotPos = vsName.indexOf(QLatin1Char('.'));
  451. if (dotPos == -1)
  452. continue;
  453. const QString path = vsRegistry.value(vsName).toString();
  454. const int version = vsName.left(dotPos).toInt();
  455. // Check existence of various install scripts
  456. const QString vcvars32bat = path + QLatin1String("bin\\vcvars32.bat");
  457. if (QFileInfo(vcvars32bat).isFile())
  458. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86),
  459. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86, vsName),
  460. vcvars32bat, QString(), true));
  461. if (version >= 10) {
  462. // Just one common file
  463. const QString vcvarsAllbat = path + QLatin1String("vcvarsall.bat");
  464. if (QFileInfo(vcvarsAllbat).isFile()) {
  465. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86),
  466. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86, vsName),
  467. vcvarsAllbat, QLatin1String("x86"), true));
  468. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::amd64),
  469. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::amd64, vsName),
  470. vcvarsAllbat, QLatin1String("amd64"), true));
  471. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_amd64),
  472. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_amd64, vsName),
  473. vcvarsAllbat, QLatin1String("x86_amd64"), true));
  474. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::ia64),
  475. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::ia64, vsName),
  476. vcvarsAllbat, QLatin1String("ia64"), true));
  477. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_ia64),
  478. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_ia64, vsName),
  479. vcvarsAllbat, QLatin1String("x86_ia64"), true));
  480. } else {
  481. qWarning("Unable to find MSVC setup script %s in version %d", qPrintable(vcvarsAllbat), version);
  482. }
  483. } else {
  484. // Amd 64 is the preferred 64bit platform
  485. const QString vcvarsAmd64bat = path + QLatin1String("bin\\amd64\\vcvarsamd64.bat");
  486. if (QFileInfo(vcvarsAmd64bat).isFile())
  487. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::amd64),
  488. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::amd64, vsName),
  489. vcvarsAmd64bat, QString(), true));
  490. const QString vcvarsX86_amd64bat = path + QLatin1String("bin\\vcvarsx86_amd64.bat");
  491. if (QFileInfo(vcvarsX86_amd64bat).isFile())
  492. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_amd64),
  493. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_amd64, vsName),
  494. vcvarsX86_amd64bat, QString(), true));
  495. const QString vcvars64bat = path + QLatin1String("bin\\vcvars64.bat");
  496. if (QFileInfo(vcvars64bat).isFile())
  497. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::amd64),
  498. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::amd64, vsName),
  499. vcvars64bat, QString(), true));
  500. const QString vcvarsX86_ia64bat = path + QLatin1String("bin\\vcvarsx86_ia64.bat");
  501. if (QFileInfo(vcvarsX86_ia64bat).isFile())
  502. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_ia64),
  503. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_ia64, vsName),
  504. vcvarsX86_ia64bat, QString(), true));
  505. }
  506. }
  507. return results;
  508. }
  509. bool MsvcToolChain::operator ==(const ToolChain &other) const
  510. {
  511. if (!AbstractMsvcToolChain::operator ==(other))
  512. return false;
  513. const MsvcToolChain *msvcTc = static_cast<const MsvcToolChain *>(&other);
  514. return m_varsBatArg == msvcTc->m_varsBatArg;
  515. }
  516. bool MsvcToolChainFactory::canRestore(const QVariantMap &data)
  517. {
  518. return idFromMap(data).startsWith(QLatin1String(Constants::MSVC_TOOLCHAIN_ID) + QLatin1Char(':'));
  519. }
  520. } // namespace Internal
  521. } // namespace ProjectExplorer