PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/plugins/projectexplorer/msvctoolchain.cpp

https://github.com/CNOT/julia-studio
C++ | 577 lines | 466 code | 55 blank | 56 comment | 71 complexity | 3d5a64e2d2c6421207dd32e6aa5feb25 MD5 | raw file
Possible License(s): GPL-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. }
  227. predefinedMacros += "#define ";
  228. predefinedMacros += key;
  229. predefinedMacros += ' ';
  230. predefinedMacros += value;
  231. predefinedMacros += '\n';
  232. }
  233. }
  234. if (debug)
  235. qDebug() << "msvcPredefinedMacros" << predefinedMacros;
  236. return predefinedMacros;
  237. }
  238. // Windows: Expand the delayed evaluation references returned by the
  239. // SDK setup scripts: "PATH=!Path!;foo". Some values might expand
  240. // to empty and should not be added
  241. static QString winExpandDelayedEnvReferences(QString in, const Utils::Environment &env)
  242. {
  243. const QChar exclamationMark = QLatin1Char('!');
  244. for (int pos = 0; pos < in.size(); ) {
  245. // Replace "!REF!" by its value in process environment
  246. pos = in.indexOf(exclamationMark, pos);
  247. if (pos == -1)
  248. break;
  249. const int nextPos = in.indexOf(exclamationMark, pos + 1);
  250. if (nextPos == -1)
  251. break;
  252. const QString var = in.mid(pos + 1, nextPos - pos - 1);
  253. const QString replacement = env.value(var.toUpper());
  254. in.replace(pos, nextPos + 1 - pos, replacement);
  255. pos += replacement.size();
  256. }
  257. return in;
  258. }
  259. Utils::Environment MsvcToolChain::readEnvironmentSetting(Utils::Environment& env) const
  260. {
  261. Utils::Environment result = env;
  262. if (!QFileInfo(m_vcvarsBat).exists())
  263. return result;
  264. QMap<QString, QString> envPairs;
  265. if (!generateEnvironmentSettings(env, m_vcvarsBat, m_varsBatArg, envPairs))
  266. return result;
  267. // Now loop through and process them
  268. QMap<QString,QString>::const_iterator envIter;
  269. for (envIter = envPairs.begin(); envIter!=envPairs.end(); ++envIter) {
  270. const QString expandedValue = winExpandDelayedEnvReferences(envIter.value(), env);
  271. if (!expandedValue.isEmpty())
  272. result.set(envIter.key(), expandedValue);
  273. }
  274. if (debug) {
  275. const QStringList newVars = result.toStringList();
  276. const QStringList oldVars = env.toStringList();
  277. QDebug nsp = qDebug().nospace();
  278. foreach (const QString &n, newVars) {
  279. if (!oldVars.contains(n))
  280. nsp << n << '\n';
  281. }
  282. }
  283. return result;
  284. }
  285. // --------------------------------------------------------------------------
  286. // MsvcToolChain
  287. // --------------------------------------------------------------------------
  288. MsvcToolChain::MsvcToolChain(const QString &name, const Abi &abi,
  289. const QString &varsBat, const QString &varsBatArg, bool autodetect) :
  290. AbstractMsvcToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), autodetect, abi, varsBat),
  291. m_varsBatArg(varsBatArg)
  292. {
  293. Q_ASSERT(!name.isEmpty());
  294. setDisplayName(name);
  295. }
  296. MsvcToolChain::MsvcToolChain() :
  297. AbstractMsvcToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), false)
  298. {
  299. }
  300. MsvcToolChain *MsvcToolChain::readFromMap(const QVariantMap &data)
  301. {
  302. MsvcToolChain *tc = new MsvcToolChain;
  303. if (tc->fromMap(data))
  304. return tc;
  305. delete tc;
  306. return 0;
  307. }
  308. QString MsvcToolChain::type() const
  309. {
  310. return QLatin1String("msvc");
  311. }
  312. QString MsvcToolChain::typeDisplayName() const
  313. {
  314. return MsvcToolChainFactory::tr("MSVC");
  315. }
  316. QList<Utils::FileName> MsvcToolChain::suggestedMkspecList() const
  317. {
  318. switch (m_abi.osFlavor()) {
  319. case ProjectExplorer::Abi::WindowsMsvc2005Flavor:
  320. return QList<Utils::FileName>() << Utils::FileName::fromString(QLatin1String("win32-msvc2005"));
  321. case ProjectExplorer::Abi::WindowsMsvc2008Flavor:
  322. return QList<Utils::FileName>() << Utils::FileName::fromString(QLatin1String("win32-msvc2008"));
  323. case ProjectExplorer::Abi::WindowsMsvc2010Flavor:
  324. return QList<Utils::FileName>() << Utils::FileName::fromString(QLatin1String("win32-msvc2010"));
  325. case ProjectExplorer::Abi::WindowsMsvc2012Flavor:
  326. QList<Utils::FileName>()
  327. << Utils::FileName::fromString(QLatin1String("win32-msvc2012"))
  328. << Utils::FileName::fromString(QLatin1String("win32-msvc2010"));
  329. break;
  330. default:
  331. break;
  332. }
  333. return QList<Utils::FileName>();
  334. }
  335. QVariantMap MsvcToolChain::toMap() const
  336. {
  337. QVariantMap data = ToolChain::toMap();
  338. data.insert(QLatin1String(varsBatKeyC), m_vcvarsBat);
  339. if (!m_varsBatArg.isEmpty())
  340. data.insert(QLatin1String(varsBatArgKeyC), m_varsBatArg);
  341. data.insert(QLatin1String(supportedAbiKeyC), m_abi.toString());
  342. return data;
  343. }
  344. bool MsvcToolChain::fromMap(const QVariantMap &data)
  345. {
  346. if (!ToolChain::fromMap(data))
  347. return false;
  348. m_vcvarsBat = data.value(QLatin1String(varsBatKeyC)).toString();
  349. m_varsBatArg = data.value(QLatin1String(varsBatArgKeyC)).toString();
  350. const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
  351. m_abi = Abi(abiString);
  352. return !m_vcvarsBat.isEmpty() && m_abi.isValid();
  353. }
  354. ToolChainConfigWidget *MsvcToolChain::configurationWidget()
  355. {
  356. return new MsvcToolChainConfigWidget(this);
  357. }
  358. ToolChain *MsvcToolChain::clone() const
  359. {
  360. return new MsvcToolChain(*this);
  361. }
  362. // --------------------------------------------------------------------------
  363. // MsvcToolChainConfigWidget
  364. // --------------------------------------------------------------------------
  365. MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) :
  366. ToolChainConfigWidget(tc),
  367. m_varsBatDisplayLabel(new QLabel(this))
  368. {
  369. m_mainLayout->addRow(new QLabel(tc->displayName()));
  370. m_varsBatDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
  371. m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayLabel);
  372. addErrorLabel();
  373. setFromToolChain();
  374. }
  375. void MsvcToolChainConfigWidget::setFromToolChain()
  376. {
  377. MsvcToolChain *tc = static_cast<MsvcToolChain *>(toolChain());
  378. QTC_ASSERT(tc, return);
  379. QString varsBatDisplay = tc->varsBat();
  380. if (!tc->varsBatArg().isEmpty()) {
  381. varsBatDisplay += QLatin1Char(' ');
  382. varsBatDisplay += tc->varsBatArg();
  383. }
  384. m_varsBatDisplayLabel->setText(varsBatDisplay);
  385. }
  386. // --------------------------------------------------------------------------
  387. // MsvcToolChainFactory
  388. // --------------------------------------------------------------------------
  389. QString MsvcToolChainFactory::displayName() const
  390. {
  391. return tr("MSVC");
  392. }
  393. QString MsvcToolChainFactory::id() const
  394. {
  395. return QLatin1String(Constants::MSVC_TOOLCHAIN_ID);
  396. }
  397. QList<ToolChain *> MsvcToolChainFactory::autoDetect()
  398. {
  399. QList<ToolChain *> results;
  400. // 1) Installed SDKs preferred over standalone Visual studio
  401. const QSettings sdkRegistry(QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows"),
  402. QSettings::NativeFormat);
  403. const QString defaultSdkPath = sdkRegistry.value(QLatin1String("CurrentInstallFolder")).toString();
  404. if (!defaultSdkPath.isEmpty()) {
  405. foreach (const QString &sdkKey, sdkRegistry.childGroups()) {
  406. const QString name = sdkRegistry.value(sdkKey + QLatin1String("/ProductName")).toString();
  407. const QString version = sdkRegistry.value(sdkKey + QLatin1String("/ProductVersion")).toString();
  408. const QString folder = sdkRegistry.value(sdkKey + QLatin1String("/InstallationFolder")).toString();
  409. if (folder.isEmpty())
  410. continue;
  411. QDir dir(folder);
  412. if (!dir.cd(QLatin1String("bin")))
  413. continue;
  414. QFileInfo fi(dir, QLatin1String("SetEnv.cmd"));
  415. if (!fi.exists())
  416. continue;
  417. QList<ToolChain *> tmp;
  418. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
  419. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, version),
  420. fi.absoluteFilePath(), QLatin1String("/x86"), true));
  421. // Add all platforms
  422. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
  423. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, version),
  424. fi.absoluteFilePath(), QLatin1String("/amd64"), true));
  425. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64),
  426. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64, version),
  427. fi.absoluteFilePath(), QLatin1String("/x86_amd64"), true));
  428. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
  429. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, version),
  430. fi.absoluteFilePath(), QLatin1String("/ia64"), true));
  431. tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64),
  432. findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64, version),
  433. fi.absoluteFilePath(), QLatin1String("/x86_ia64"), true));
  434. // Make sure the default is front.
  435. if (folder == defaultSdkPath)
  436. results = tmp + results;
  437. else
  438. results += tmp;
  439. } // foreach
  440. }
  441. // 2) Installed MSVCs
  442. const QSettings vsRegistry(
  443. #ifdef Q_OS_WIN64
  444. QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7"),
  445. #else
  446. QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7"),
  447. #endif
  448. QSettings::NativeFormat);
  449. foreach (const QString &vsName, vsRegistry.allKeys()) {
  450. // Scan for version major.minor
  451. const int dotPos = vsName.indexOf(QLatin1Char('.'));
  452. if (dotPos == -1)
  453. continue;
  454. const QString path = vsRegistry.value(vsName).toString();
  455. const int version = vsName.left(dotPos).toInt();
  456. // Check existence of various install scripts
  457. const QString vcvars32bat = path + QLatin1String("bin\\vcvars32.bat");
  458. if (QFileInfo(vcvars32bat).isFile())
  459. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86),
  460. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86, vsName),
  461. vcvars32bat, QString(), true));
  462. if (version >= 10) {
  463. // Just one common file
  464. const QString vcvarsAllbat = path + QLatin1String("vcvarsall.bat");
  465. if (QFileInfo(vcvarsAllbat).isFile()) {
  466. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86),
  467. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86, vsName),
  468. vcvarsAllbat, QLatin1String("x86"), true));
  469. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::amd64),
  470. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::amd64, vsName),
  471. vcvarsAllbat, QLatin1String("amd64"), true));
  472. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_amd64),
  473. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_amd64, vsName),
  474. vcvarsAllbat, QLatin1String("x86_amd64"), true));
  475. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::ia64),
  476. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::ia64, vsName),
  477. vcvarsAllbat, QLatin1String("ia64"), true));
  478. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_ia64),
  479. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_ia64, vsName),
  480. vcvarsAllbat, QString("x86_ia64"), true));
  481. } else {
  482. qWarning("Unable to find MSVC setup script %s in version %d", qPrintable(vcvarsAllbat), version);
  483. }
  484. } else {
  485. // Amd 64 is the preferred 64bit platform
  486. const QString vcvarsAmd64bat = path + QLatin1String("bin\\amd64\\vcvarsamd64.bat");
  487. if (QFileInfo(vcvarsAmd64bat).isFile())
  488. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::amd64),
  489. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::amd64, vsName),
  490. vcvarsAmd64bat, QString(), true));
  491. const QString vcvarsX86_amd64bat = path + QLatin1String("bin\\vcvarsx86_amd64.bat");
  492. if (QFileInfo(vcvarsX86_amd64bat).isFile())
  493. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_amd64),
  494. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_amd64, vsName),
  495. vcvarsX86_amd64bat, QString(), true));
  496. const QString vcvars64bat = path + QLatin1String("bin\\vcvars64.bat");
  497. if (QFileInfo(vcvars64bat).isFile())
  498. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::amd64),
  499. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::amd64, vsName),
  500. vcvars64bat, QString(), true));
  501. const QString vcvarsX86_ia64bat = path + QLatin1String("bin\\vcvarsx86_ia64.bat");
  502. if (QFileInfo(vcvarsX86_ia64bat).isFile())
  503. results.append(new MsvcToolChain(generateDisplayName(vsName, MsvcToolChain::VS, MsvcToolChain::x86_ia64),
  504. findAbiOfMsvc(MsvcToolChain::VS, MsvcToolChain::x86_ia64, vsName),
  505. vcvarsX86_ia64bat, QString(), true));
  506. }
  507. }
  508. return results;
  509. }
  510. bool MsvcToolChain::operator ==(const ToolChain &other) const
  511. {
  512. if (!AbstractMsvcToolChain::operator ==(other))
  513. return false;
  514. const MsvcToolChain *msvcTc = static_cast<const MsvcToolChain *>(&other);
  515. return m_varsBatArg == msvcTc->m_varsBatArg;
  516. }
  517. bool MsvcToolChainFactory::canRestore(const QVariantMap &data)
  518. {
  519. return idFromMap(data).startsWith(QLatin1String(Constants::MSVC_TOOLCHAIN_ID) + QLatin1Char(':'));
  520. }
  521. } // namespace Internal
  522. } // namespace ProjectExplorer