PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/plugins/projectexplorer/msvctoolchain.cpp

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