From 6ac7efba15c7678a55285e0d2e059b01758389e3 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Wed, 23 Feb 2011 14:57:52 +0100
Subject: [PATCH] Debugger: Move debugger executables configuration into
 toolchains.

---
 src/plugins/debugger/cdb/cdbengine.cpp        |  17 +-
 src/plugins/debugger/cdb/cdboptions.cpp       | 166 +------------
 src/plugins/debugger/cdb/cdboptions.h         |   9 +-
 src/plugins/debugger/cdb/cdboptionspage.cpp   | 171 +-------------
 src/plugins/debugger/cdb/cdboptionspage.h     |  15 +-
 .../debugger/cdb/cdboptionspagewidget.ui      |  61 +----
 src/plugins/debugger/commonoptionspage.cpp    | 222 ------------------
 src/plugins/debugger/commonoptionspage.h      |  10 -
 src/plugins/debugger/commonoptionspage.ui     |  30 +--
 src/plugins/debugger/debuggerplugin.cpp       |  10 +-
 src/plugins/projectexplorer/gcctoolchain.cpp  |   1 +
 src/plugins/projectexplorer/msvctoolchain.cpp |  42 ++++
 src/plugins/projectexplorer/msvctoolchain.h   |  19 ++
 13 files changed, 112 insertions(+), 661 deletions(-)

diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index ccc88c30822..d26f25159a8 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -637,7 +637,19 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa
     // Determine extension lib name and path to use
     // The extension is passed as relative name with the path variable set
     //(does not work with absolute path names)
-    const QFileInfo extensionFi(CdbEngine::extensionLibraryName(m_options->is64bit));
+    const QString executable = debuggerCore()->debuggerForAbi(sp.toolChainAbi);
+    if (executable.isEmpty()) {
+        *errorMessage = tr("There is no CDB executable specified.");
+        return false;
+    }
+
+    const bool is64bit =
+#ifdef Q_OS_WIN
+            Utils::winIs64BitBinary(executable);
+#else
+            false;
+#endif
+    const QFileInfo extensionFi(CdbEngine::extensionLibraryName(is64bit));
     if (!extensionFi.isFile()) {
         *errorMessage = QString::fromLatin1("Internal error: The extension %1 cannot be found.").
                 arg(QDir::toNativeSeparators(extensionFi.absoluteFilePath()));
@@ -690,7 +702,6 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa
         nativeArguments += sp.processArgs;
     }
 
-    const QString executable = m_options->executable;
     const QString msg = QString::fromLatin1("Launching %1 %2\nusing %3 of %4.").
             arg(QDir::toNativeSeparators(executable),
                 arguments.join(QString(blank)) + blank + nativeArguments,
@@ -1119,7 +1130,7 @@ void CdbEngine::handleJumpToLineAddressResolution(const CdbBuiltinCommandPtr &cm
     QByteArray registerCmd;
     ByteArrayInputStream str(registerCmd);
     // PC-register depending on 64/32bit.
-    str << "r " << (m_options->is64bit ? "rip" : "eip") << "=0x" << answer;
+    str << "r " << (startParameters().toolChainAbi.wordWidth() == 64 ? "rip" : "eip") << "=0x" << answer;
     postCommand(registerCmd, 0);
     gotoLocation(Location(cookie.fileName, cookie.lineNumber));
 }
diff --git a/src/plugins/debugger/cdb/cdboptions.cpp b/src/plugins/debugger/cdb/cdboptions.cpp
index 2481f629ae6..fe91471d998 100644
--- a/src/plugins/debugger/cdb/cdboptions.cpp
+++ b/src/plugins/debugger/cdb/cdboptions.cpp
@@ -32,31 +32,20 @@
 **************************************************************************/
 
 #include "cdboptions.h"
-#include "cdbengine.h"
-
-#ifdef Q_OS_WIN
-#    include <utils/winutils.h>
-#endif
 
 #include <QtCore/QSettings>
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtCore/QCoreApplication>
 
 static const char settingsGroupC[] = "CDB2";
 static const char enabledKeyC[] = "Enabled";
-static const char pathKeyC[] = "Path";
 static const char symbolPathsKeyC[] = "SymbolPaths";
 static const char sourcePathsKeyC[] = "SourcePaths";
 static const char breakEventKeyC[] = "BreakEvent";
-static const char is64bitKeyC[] = "64bit";
 static const char additionalArgumentsKeyC[] = "AdditionalArguments";
 
 namespace Debugger {
 namespace Internal {
 
-CdbOptions::CdbOptions() :
-    enabled(false), is64bit(false)
+CdbOptions::CdbOptions() : enabled(false)
 {
 }
 
@@ -65,90 +54,23 @@ QString CdbOptions::settingsGroup()
     return QLatin1String(settingsGroupC);
 }
 
-void CdbOptions::clearExecutable()
-{
-    is64bit = enabled = false;
-    executable.clear();
-}
-
 void CdbOptions::clear()
 {
-    clearExecutable();
+    enabled = false;
     symbolPaths.clear();
     sourcePaths.clear();
 }
 
-static inline QString msgAutoDetectFail(bool is64Bit, const QString &executable,
-                                        const QString &extLib)
-{
-    return QCoreApplication::translate("Debugger::Cdb::CdbOptions",
-        "Auto-detection of the CDB debugging engine (%1bit) failed:\n"
-        "Debugger executable: %2\n"
-        "Extension library  : %3 not present.\n").arg(is64Bit ? 64 : 32).
-         arg(QDir::toNativeSeparators(executable), QDir::toNativeSeparators(extLib));
-}
-
-static inline QString msgAutoDetect(bool is64Bit, const QString &executable,
-                                    const QString &extLib,
-                                    const QStringList &symbolPaths)
-{
-    return QCoreApplication::translate("Debugger::Cdb::CdbOptions",
-        "The new CDB debugging engine (%1bit) has been set up automatically:\n"
-        "Debugger executable: %2\n"
-        "Extension library  : %3\n"
-        "Symbol paths       : %4\n").arg(is64Bit ? 64 : 32).
-        arg(QDir::toNativeSeparators(executable), QDir::toNativeSeparators(extLib),
-        symbolPaths.join(QString(QLatin1Char(';'))));
-}
-
 QStringList CdbOptions::oldEngineSymbolPaths(const QSettings *s)
 {
     return s->value(QLatin1String("CDB/SymbolPaths")).toStringList();
 }
 
-bool CdbOptions::autoDetect(const QSettings *s)
-{
-    QString autoExecutable;
-    bool auto64Bit;
-    // Check installation  and existence of the extension library
-    CdbOptions::autoDetectExecutable(&autoExecutable, &auto64Bit);
-    if (autoExecutable.isEmpty())
-        return false;
-    const QString extLib = CdbEngine::extensionLibraryName(auto64Bit);
-    if (!QFileInfo(extLib).isFile()) {
-        const QString failMsg = msgAutoDetectFail(auto64Bit, autoExecutable, extLib);
-        qWarning("%s", qPrintable(failMsg));
-          clearExecutable();
-        return false;
-    }
-    enabled = true;
-    is64bit = auto64Bit;
-    executable = autoExecutable;
-    // Is there a symbol path from an old install? Use that
-    if (symbolPaths.empty())
-        symbolPaths = CdbOptions::oldEngineSymbolPaths(s);
-    const QString msg = msgAutoDetect(is64bit, QDir::toNativeSeparators(executable),
-                                      QDir::toNativeSeparators(extLib), symbolPaths);
-    qWarning("%s", qPrintable(msg));
-    return true;
-}
-
 void CdbOptions::fromSettings(QSettings *s)
 {
     clear();
-    // Is this the first time we are called ->
-    // try to find automatically
     const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/');
-    const QString enabledKey = keyRoot + QLatin1String(enabledKeyC);
-    // First-time autodetection: Write back parameters
-    const bool firstTime = !s->contains(enabledKey);
-    if (firstTime && autoDetect(s)) {
-        toSettings(s);
-        return;
-    }
-    enabled = s->value(enabledKey, false).toBool();
-    is64bit = s->value(keyRoot + QLatin1String(is64bitKeyC), is64bit).toBool();
-    executable = s->value(keyRoot + QLatin1String(pathKeyC), executable).toString();
+    enabled = s->value(keyRoot + QLatin1String(enabledKeyC), QVariant(false)).toBool();
     additionalArguments = s->value(keyRoot + QLatin1String(additionalArgumentsKeyC), QString()).toString();
     symbolPaths = s->value(keyRoot + QLatin1String(symbolPathsKeyC), QStringList()).toStringList();
     sourcePaths = s->value(keyRoot + QLatin1String(sourcePathsKeyC), QStringList()).toStringList();
@@ -159,8 +81,6 @@ void CdbOptions::toSettings(QSettings *s) const
 {
     s->beginGroup(QLatin1String(settingsGroupC));
     s->setValue(QLatin1String(enabledKeyC), enabled);
-    s->setValue(QLatin1String(pathKeyC), executable);
-    s->setValue(QLatin1String(is64bitKeyC), is64bit);
     s->setValue(QLatin1String(symbolPathsKeyC), symbolPaths);
     s->setValue(QLatin1String(sourcePathsKeyC), sourcePaths);
     s->setValue(QLatin1String(breakEventKeyC), breakEvents);
@@ -170,91 +90,13 @@ void CdbOptions::toSettings(QSettings *s) const
 
 bool CdbOptions::equals(const CdbOptions &rhs) const
 {
-    return enabled == rhs.enabled && is64bit == rhs.is64bit
-            && executable == rhs.executable
+    return enabled == rhs.enabled
             && additionalArguments == rhs.additionalArguments
             && symbolPaths == rhs.symbolPaths
             && sourcePaths == rhs.sourcePaths
             && breakEvents == rhs.breakEvents;
 }
 
-// Check the CDB executable and accumulate the list of checked paths
-// for reporting.
-static QString checkCdbExecutable(const QString &programDir, const QString &postfix,
-                               QStringList *checkedDirectories = 0)
-{
-    QString executable = programDir;
-    executable += QLatin1String("/Debugging Tools For Windows");
-    executable += postfix;
-    if (checkedDirectories)
-        checkedDirectories->push_back(QDir::toNativeSeparators(executable));
-    executable += QLatin1String("/cdb.exe");
-    const QFileInfo fi(executable);
-    return fi.isFile() && fi.isExecutable() ? fi.absoluteFilePath() : QString();
-}
-
-bool CdbOptions::autoDetectExecutable(QString *outPath, bool *is64bitIn  /* = 0 */,
-                                      QStringList *checkedDirectories /* = 0 */)
-{
-    // Look for $ProgramFiles/"Debugging Tools For Windows <bit-idy>/cdb.exe" and its
-    // " (x86)", " (x64)" variations.
-    static const char *postFixes[] = {" (x64)", " 64-bit", " (x86)", " (x32)" };
-    enum { first32bitIndex = 2 };
-
-    outPath->clear();
-    if (checkedDirectories)
-        checkedDirectories->clear();
-
-    const QString programDir = QString::fromLocal8Bit(qgetenv("ProgramFiles"));
-    if (programDir.isEmpty())
-        return false;
-
-#ifdef Q_OS_WIN
-    const bool systemIs64Bit = Utils::winIs64BitSystem();
-#else
-    const bool systemIs64Bit = false;
-#endif
-    // Plain system installation. 32/64 Bit matches the system.
-    *outPath = checkCdbExecutable(programDir, QString(), checkedDirectories);
-    if (!outPath->isEmpty()) {
-        if (is64bitIn)
-            *is64bitIn = systemIs64Bit;
-        return true;
-    }
-    // Try the post fixes
-    for (unsigned i = 0; i < sizeof(postFixes)/sizeof(const char*); i++) {
-        *outPath = checkCdbExecutable(programDir, QLatin1String(postFixes[i]), checkedDirectories);
-        if (!outPath->isEmpty()) {
-            if (is64bitIn)
-                *is64bitIn = i < first32bitIndex;
-            return true;
-        }
-    }
-    // A 32bit-compile running on a 64bit system sees the 64 bit installation
-    // as "$ProgramFiles (x64)/Debugging Tools..." and (untested), a 64 bit-
-    // compile running on a 64bit system sees the 32 bit installation as
-    // "$ProgramFiles (x86)/Debugging Tools..." (assuming this works at all)
-#ifdef Q_OS_WIN64
-    *outPath = checkCdbExecutable(programDir + QLatin1String(" (x32)"), QString(), checkedDirectories);
-    if (!outPath->isEmpty()) {
-        if (is64bitIn)
-            *is64bitIn = false;
-        return true;
-    }
-#else
-    // A 32bit process on 64 bit sees "ProgramFiles\Debg.. (x64)"
-    if (programDir.endsWith(QLatin1String(" (x86)"))) {
-        *outPath = checkCdbExecutable(programDir.left(programDir.size() - 6),
-                                      QLatin1String(" (x64)"), checkedDirectories);
-        if (!outPath->isEmpty()) {
-            if (is64bitIn)
-                *is64bitIn = true;
-            return true;
-        }
-    }
-#endif
-    return false;
-}
 
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdboptions.h b/src/plugins/debugger/cdb/cdboptions.h
index 828d9714938..5ebd85fd426 100644
--- a/src/plugins/debugger/cdb/cdboptions.h
+++ b/src/plugins/debugger/cdb/cdboptions.h
@@ -48,26 +48,19 @@ struct CdbOptions
 public:
     CdbOptions();
 
-    bool isValid() const { return enabled && !executable.isEmpty(); }
+    bool isValid() const { return enabled; }
 
-    void clearExecutable();
     void clear();
 
     void fromSettings(QSettings *s); // Writes parameters on first-time autodetect
-    bool autoDetect(const QSettings *s);
     void toSettings(QSettings *s) const;
 
     bool equals(const CdbOptions &rhs) const;
 
-    static bool autoDetectExecutable(QString *outPath, bool *is64bit = 0,
-                                     QStringList *checkedDirectories = 0);
-
     static QString settingsGroup();
     static QStringList oldEngineSymbolPaths(const QSettings *s);
 
     bool enabled;
-    bool is64bit;
-    QString executable;
     QString additionalArguments;
     QStringList symbolPaths;
     QStringList sourcePaths;
diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp
index 3f66358e94c..015bae61f8f 100644
--- a/src/plugins/debugger/cdb/cdboptionspage.cpp
+++ b/src/plugins/debugger/cdb/cdboptionspage.cpp
@@ -36,27 +36,13 @@
 #include "debuggerconstants.h"
 #include "cdbengine.h"
 
-#ifdef Q_OS_WIN
-#    include <utils/winutils.h>
-#endif
 #include <utils/synchronousprocess.h>
 
 #include <coreplugin/icore.h>
 
-#include <QtCore/QCoreApplication>
-#include <QtCore/QUrl>
-#include <QtCore/QFileInfo>
-#include <QtCore/QDir>
-#include <QtCore/QDateTime>
 #include <QtCore/QTextStream>
-#include <QtCore/QTimer>
-#include <QtCore/QProcess>
-#include <QtGui/QMessageBox>
 #include <QtGui/QLineEdit>
-#include <QtGui/QDesktopServices>
-
-static const char *dgbToolsDownloadLink32C = "http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx";
-static const char *dgbToolsDownloadLink64C = "http://www.microsoft.com/whdc/devtools/debugging/install64bit.Mspx";
+#include <QtGui/QCheckBox>
 
 namespace Debugger {
 namespace Internal {
@@ -173,35 +159,11 @@ QStringList CdbBreakEventWidget::breakEvents() const
     return rc;
 }
 
-static inline QString msgPathConfigNote()
-{
-#ifdef Q_OS_WIN
-    const bool is64bit = Utils::winIs64BitSystem();
-#else
-    const bool is64bit = false;
-#endif
-    const QString link = is64bit ? QLatin1String(dgbToolsDownloadLink64C) : QLatin1String(dgbToolsDownloadLink32C);
-    //: Label text for path configuration. %2 is "x-bit version".
-    return CdbOptionsPageWidget::tr(
-    "<html><body><p>Specify the path to the "
-    "<a href=\"%1\">Windows Console Debugger executable</a>"
-    " (%2) here.</p>"
-    "</body></html>").arg(link, (is64bit ? CdbOptionsPageWidget::tr("64-bit version")
-                                         : CdbOptionsPageWidget::tr("32-bit version")));
-}
-
 CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
-    QWidget(parent), m_breakEventWidget(new CdbBreakEventWidget),
-    m_reportTimer(0)
+    QWidget(parent), m_breakEventWidget(new CdbBreakEventWidget)
 {
     m_ui.setupUi(this);
-    m_ui.noteLabel->setText(msgPathConfigNote());
-    m_ui.noteLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-    connect(m_ui.noteLabel, SIGNAL(linkActivated(QString)), this, SLOT(downLoadLinkActivated(QString)));
 
-    m_ui.pathChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
-    m_ui.pathChooser->addButton(tr("Autodetect"), this, SLOT(autoDetect()));
-    m_ui.cdbPathGroupBox->installEventFilter(this);
     QVBoxLayout *eventLayout = new QVBoxLayout;
     eventLayout->addWidget(m_breakEventWidget);
     m_ui.eventGroupBox->setLayout(eventLayout);
@@ -209,32 +171,18 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
 
 void CdbOptionsPageWidget::setOptions(CdbOptions &o)
 {
-    m_ui.pathChooser->setPath(o.executable);
     m_ui.additionalArgumentsLineEdit->setText(o.additionalArguments);
-    m_ui.is64BitCheckBox->setChecked(o.is64bit);
     m_ui.cdbPathGroupBox->setChecked(o.enabled);
     setSymbolPaths(o.symbolPaths);
     m_ui.sourcePathListEditor->setPathList(o.sourcePaths);
     m_breakEventWidget->setBreakEvents(o.breakEvents);
 }
 
-bool CdbOptionsPageWidget::is64Bit() const
-{
-    return m_ui.is64BitCheckBox->isChecked();
-}
-
-QString CdbOptionsPageWidget::path() const
-{
-    return m_ui.pathChooser->path();
-}
-
 CdbOptions CdbOptionsPageWidget::options() const
 {
     CdbOptions  rc;
-    rc.executable = path();
     rc.additionalArguments = m_ui.additionalArgumentsLineEdit->text().trimmed();
     rc.enabled = m_ui.cdbPathGroupBox->isChecked();
-    rc.is64bit = is64Bit();
     rc.symbolPaths = symbolPaths();
     rc.sourcePaths = m_ui.sourcePathListEditor->pathList();
     rc.breakEvents = m_breakEventWidget->breakEvents();
@@ -251,128 +199,15 @@ void CdbOptionsPageWidget::setSymbolPaths(const QStringList &s)
     m_ui.symbolPathListEditor->setPathList(s);
 }
 
-void CdbOptionsPageWidget::hideReportLabel()
-{
-    m_ui.reportLabel->clear();
-    m_ui.reportLabel->setVisible(false);
-}
-
-void CdbOptionsPageWidget::autoDetect()
-{
-    QString executable;
-    QStringList checkedDirectories;
-    bool is64bit;
-    const bool ok = CdbOptions::autoDetectExecutable(&executable, &is64bit, &checkedDirectories);
-    m_ui.cdbPathGroupBox->setChecked(ok);
-    if (ok) {
-        m_ui.is64BitCheckBox->setChecked(is64bit);
-        m_ui.pathChooser->setPath(executable);
-        QString report;
-        // Now check for the extension library as well.
-        const bool allOk = checkInstallation(executable, is64Bit(), &report);
-        setReport(report, allOk);
-        // On this occasion, if no symbol paths are specified, check for an
-        // old CDB installation
-        if (symbolPaths().isEmpty())
-            setSymbolPaths(CdbOptions::oldEngineSymbolPaths(Core::ICore::instance()->settings()));
-    } else {
-        const QString msg = tr("\"Debugging Tools for Windows\" could not be found.");
-        const QString details = tr("Checked:\n%1").arg(checkedDirectories.join(QString(QLatin1Char('\n'))));
-        QMessageBox msbBox(QMessageBox::Information, tr("Autodetection"), msg, QMessageBox::Ok, this);
-        msbBox.setDetailedText(details);
-        msbBox.exec();
-    }
-}
-
-void CdbOptionsPageWidget::setReport(const QString &msg, bool success)
-{
-    // Hide label after some interval
-    if (!m_reportTimer) {
-        m_reportTimer = new QTimer(this);
-        m_reportTimer->setSingleShot(true);
-        connect(m_reportTimer, SIGNAL(timeout()), this, SLOT(hideReportLabel()));
-    } else {
-        if (m_reportTimer->isActive())
-            m_reportTimer->stop();
-    }
-    m_reportTimer->setInterval(success ? 10000 : 20000);
-    m_reportTimer->start();
-
-    m_ui.reportLabel->setText(msg);
-    m_ui.reportLabel->setStyleSheet(success ? QString() : QString::fromAscii("background-color : 'red'"));
-    m_ui.reportLabel->setVisible(true);
-}
-
-void CdbOptionsPageWidget::downLoadLinkActivated(const QString &link)
-{
-    QDesktopServices::openUrl(QUrl(link));
-}
-
 QString CdbOptionsPageWidget::searchKeywords() const
 {
     QString rc;
-    QTextStream(&rc) << m_ui.pathLabel->text() << ' ' << m_ui.symbolPathLabel->text()
+    QTextStream(&rc) << m_ui.symbolPathLabel->text()
             << ' ' << m_ui.sourcePathLabel->text();
     rc.remove(QLatin1Char('&'));
     return rc;
 }
 
-static QString cdbVersion(const QString &executable)
-{
-    QProcess cdb;
-    cdb.start(executable, QStringList(QLatin1String("-version")));
-    cdb.closeWriteChannel();
-    if (!cdb.waitForStarted())
-        return QString();
-    if (!cdb.waitForFinished()) {
-        Utils::SynchronousProcess::stopProcess(cdb);
-        return QString();
-    }
-    return QString::fromLocal8Bit(cdb.readAllStandardOutput());
-}
-
-bool CdbOptionsPageWidget::checkInstallation(const QString &executable,
-                                             bool is64Bit, QString *message)
-{
-    // 1) Check on executable
-    unsigned checkedItems = 0;
-    QString rc;
-    if (executable.isEmpty()) {
-        message->append(tr("No cdb executable specified.\n"));
-    } else {
-        const QString version = cdbVersion(executable);
-        if (version.isEmpty()) {
-            message->append(tr("Unable to determine version of %1.\n").
-                            arg(executable));
-        } else {
-            message->append(tr("Version: %1").arg(version));
-            checkedItems++;
-        }
-    }
-
-    // 2) Check on extension library
-    const QFileInfo extensionFi(CdbEngine::extensionLibraryName(is64Bit));
-    if (extensionFi.isFile()) {
-        message->append(tr("Extension library: %1, built: %2.\n").
-                        arg(QDir::toNativeSeparators(extensionFi.absoluteFilePath())).
-                        arg(extensionFi.lastModified().toString(Qt::SystemLocaleShortDate)));
-        checkedItems++;
-    } else {
-        message->append("Extension library not found.\n");
-    }
-    return checkedItems == 2u;
-}
-
-bool CdbOptionsPageWidget::eventFilter(QObject *o, QEvent *e)
-{
-    if (o != m_ui.cdbPathGroupBox || e->type() != QEvent::ToolTip)
-        return QWidget::eventFilter(o, e);
-    QString message;
-    checkInstallation(path(), is64Bit(), &message);
-    m_ui.cdbPathGroupBox->setToolTip(message);
-    return false;
-}
-
 // ---------- CdbOptionsPage
 
 CdbOptionsPage *CdbOptionsPage::m_instance = 0;
diff --git a/src/plugins/debugger/cdb/cdboptionspage.h b/src/plugins/debugger/cdb/cdboptionspage.h
index 663cea9d405..ff6a42a85e2 100644
--- a/src/plugins/debugger/cdb/cdboptionspage.h
+++ b/src/plugins/debugger/cdb/cdboptionspage.h
@@ -44,7 +44,7 @@
 #include <QtCore/QSharedPointer>
 
 QT_BEGIN_NAMESPACE
-class QTimer;
+class QCheckBox;
 QT_END_NAMESPACE
 
 namespace Debugger {
@@ -81,26 +81,13 @@ public:
 
     QString searchKeywords() const;
 
-    virtual bool eventFilter(QObject *, QEvent *);
-
-private slots:
-    void autoDetect();
-    void downLoadLinkActivated(const QString &);
-    void hideReportLabel();
-
 private:
     QStringList symbolPaths() const;
     void setSymbolPaths(const QStringList &s);
-    void setReport(const QString &, bool success);
-    inline bool is64Bit() const;
     inline QString path() const;
 
-    static bool checkInstallation(const QString &executable, bool is64Bit,
-                                  QString *message);
-
     Ui::CdbOptionsPageWidget m_ui;
     CdbBreakEventWidget *m_breakEventWidget;
-    QTimer *m_reportTimer;
 };
 
 class CdbOptionsPage : public Core::IOptionsPage
diff --git a/src/plugins/debugger/cdb/cdboptionspagewidget.ui b/src/plugins/debugger/cdb/cdboptionspagewidget.ui
index 11ce969af74..7a74d5ac039 100644
--- a/src/plugins/debugger/cdb/cdboptionspagewidget.ui
+++ b/src/plugins/debugger/cdb/cdboptionspagewidget.ui
@@ -2,6 +2,14 @@
 <ui version="4.0">
  <class>Debugger::Internal::CdbOptionsPageWidget</class>
  <widget class="QWidget" name="Debugger::Internal::CdbOptionsPageWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>318</width>
+    <height>298</height>
+   </rect>
+  </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
@@ -14,27 +22,10 @@
         <bool>true</bool>
        </property>
        <layout class="QFormLayout" name="formLayout">
-        <item row="1" column="0">
-         <widget class="QLabel" name="pathLabel">
-          <property name="text">
-           <string>&amp;Path:</string>
-          </property>
-          <property name="buddy">
-           <cstring>pathChooser</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="1">
-         <widget class="Utils::PathChooser" name="pathChooser" native="true"/>
-        </item>
-        <item row="0" column="0" colspan="2">
-         <widget class="QLabel" name="noteLabel">
-          <property name="text">
-           <string notr="true" extracomment="Placeholder">Note: bla, blah</string>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="0">
+        <property name="fieldGrowthPolicy">
+         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+        </property>
+        <item row="0" column="0">
          <widget class="QLabel" name="additionalArgumentsLabel">
           <property name="text">
            <string>Additional &amp;arguments:</string>
@@ -44,16 +35,9 @@
           </property>
          </widget>
         </item>
-        <item row="3" column="1">
+        <item row="0" column="1">
          <widget class="QLineEdit" name="additionalArgumentsLineEdit"/>
         </item>
-        <item row="2" column="0">
-         <widget class="QCheckBox" name="is64BitCheckBox">
-          <property name="text">
-           <string>64 bit</string>
-          </property>
-         </widget>
-        </item>
        </layout>
       </widget>
      </item>
@@ -117,28 +101,9 @@
      </property>
     </spacer>
    </item>
-   <item>
-    <widget class="QLabel" name="reportLabel">
-     <property name="styleSheet">
-      <string notr="true"/>
-     </property>
-     <property name="wordWrap">
-      <bool>true</bool>
-     </property>
-     <property name="textInteractionFlags">
-      <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
-     </property>
-    </widget>
-   </item>
   </layout>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>Utils::PathChooser</class>
-   <extends>QWidget</extends>
-   <header location="global">utils/pathchooser.h</header>
-   <container>1</container>
-  </customwidget>
   <customwidget>
    <class>Utils::PathListEditor</class>
    <extends>QWidget</extends>
diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp
index c947cea9752..3f0e65e4593 100644
--- a/src/plugins/debugger/commonoptionspage.cpp
+++ b/src/plugins/debugger/commonoptionspage.cpp
@@ -42,8 +42,6 @@
 #include <coreplugin/manhattanstyle.h>
 
 #include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/toolchainmanager.h>
-#include <projectexplorer/abi.h>
 
 #include <QtCore/QFileInfo>
 #include <QtCore/QTextStream>
@@ -55,10 +53,6 @@ using namespace ProjectExplorer;
 namespace Debugger {
 namespace Internal {
 
-static const char *DEBUGGER_MAPPING_ARRAY = "GdbMapping";
-static const char *DEBUGGER_ABI_KEY = "Abi";
-static const char *DEBUGGER_BINARY_KEY = "Binary";
-
 ///////////////////////////////////////////////////////////////////////
 //
 // CommonOptionsPage
@@ -67,7 +61,6 @@ static const char *DEBUGGER_BINARY_KEY = "Binary";
 
 CommonOptionsPage::CommonOptionsPage()
 {
-    m_abiToDebuggerMapChanged = true;
 }
 
 QString CommonOptionsPage::id() const
@@ -96,12 +89,6 @@ QIcon CommonOptionsPage::categoryIcon() const
 void CommonOptionsPage::apply()
 {
     m_group.apply(ICore::instance()->settings());
-
-    if (m_ui.debuggerChooserWidget->isDirty()) {
-        m_abiToDebuggerMap = m_ui.debuggerChooserWidget->debuggerMapping();
-        //m_ui.debuggerChooserWidget->setDebuggerMapping(m_abiToDebuggerMap);
-        m_abiToDebuggerMapChanged = true;
-    }
 }
 
 void CommonOptionsPage::finish()
@@ -109,11 +96,6 @@ void CommonOptionsPage::finish()
     m_group.finish();
 }
 
-QString CommonOptionsPage::debuggerForAbi(const QString &abi) const
-{
-    return m_abiToDebuggerMap.value(abi);
-}
-
 QWidget *CommonOptionsPage::createPage(QWidget *parent)
 {
     QWidget *w = new QWidget(parent);
@@ -170,40 +152,6 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
 #ifndef Q_OS_WIN
     m_ui.checkBoxRegisterForPostMortem->setVisible(false);
 #endif
-
-    // Tool
-    connect(ToolChainManager::instance(),
-        SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
-        SLOT(handleToolChainAdditions(ProjectExplorer::ToolChain*)));
-
-    connect(ToolChainManager::instance(),
-        SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
-        SLOT(handleToolChainRemovals(ProjectExplorer::ToolChain*)));
-
-    // Update mapping now that toolchains are available
-    QList<ToolChain *> tcs = ToolChainManager::instance()->toolChains();
-
-    QStringList abiList;
-    foreach (ToolChain *tc, tcs) {
-        const QString abi = tc->targetAbi().toString();
-        if (!abiList.contains(abi))
-            abiList.append(abi);
-        if (!m_abiToDebuggerMap.contains(abi))
-            handleToolChainAdditions(tc);
-    }
-
-    QStringList toRemove;
-    for (QMap<QString, QString>::const_iterator i = m_abiToDebuggerMap.constBegin();
-         i != m_abiToDebuggerMap.constEnd(); ++i) {
-        if (!abiList.contains(i.key()))
-            toRemove.append(i.key());
-    }
-
-    foreach (const QString &key, toRemove)
-        m_abiToDebuggerMap.remove(key);
-
-    m_ui.debuggerChooserWidget->setDebuggerMapping(m_abiToDebuggerMap);
-
     return w;
 }
 
@@ -212,176 +160,6 @@ bool CommonOptionsPage::matches(const QString &s) const
     return m_searchKeywords.contains(s, Qt::CaseInsensitive);
 }
 
-void CommonOptionsPage::readSettings() /* static */
-{
-    // FIXME: Convert old settings!
-    QSettings *settings = Core::ICore::instance()->settings();
-
-    m_abiToDebuggerMap.clear();
-
-    int size = settings->beginReadArray(DEBUGGER_MAPPING_ARRAY);
-    for (int i = 0; i < size; ++i) {
-        settings->setArrayIndex(i);
-        Abi abi(settings->value(DEBUGGER_ABI_KEY).toString());
-        if (!abi.isValid())
-            continue;
-        QString binary = settings->value(DEBUGGER_BINARY_KEY).toString();
-        if (binary.isEmpty())
-            continue;
-        m_abiToDebuggerMap.insert(abi.toString(), binary);
-    }
-    settings->endArray();
-
-    // Map old settings (pre 2.2):
-    const QChar separator = QLatin1Char(',');
-    const QString keyRoot = QLatin1String("GdbBinaries/GdbBinaries");
-    for (int i = 1; ; i++) {
-        const QString value = settings->value(keyRoot + QString::number(i)).toString();
-        if (value.isEmpty())
-            break;
-        // Split apart comma-separated binary and its numerical toolchains.
-        QStringList tokens = value.split(separator);
-        if (tokens.size() < 2)
-            break;
-
-        const QString binary = tokens.front();
-        // Skip non-existent absolute binaries allowing for upgrades by the installer.
-        // Force a rewrite of the settings file.
-        const QFileInfo binaryInfo(binary);
-        if (binaryInfo.isAbsolute() && !binaryInfo.isExecutable()) {
-            const QString msg = QString::fromLatin1("Warning: The gdb binary '%1' does not exist, skipping.\n").arg(binary);
-            qWarning("%s", qPrintable(msg));
-            continue;
-        }
-
-        // Create entries for all toolchains.
-        tokens.pop_front();
-        foreach (const QString &t, tokens) {
-            // Paranoia: Check if the there is already a binary configured for the toolchain.
-            QString abi;
-            switch (t.toInt())
-            {
-            case 0: // GCC
-            case 1: // Linux ICC
-#ifndef Q_OS_WIN
-                abi = Abi::hostAbi().toString();
-#endif
-                break;
-            case 2: // MinGW
-            case 3: // MSVC
-            case 4: // WINCE
-#ifdef Q_OS_WIN
-                abi = Abi::hostAbi().toString();
-#endif
-                break;
-            case 5: // WINSCW
-                abi = Abi(Abi::ARM, Abi::Symbian,
-                                           Abi::Symbian_emulator,
-                                           Abi::Format_ELF,
-                                           32).toString();
-                break;
-            case 6: // GCCE
-            case 7: // RVCT 2, ARM v5
-            case 8: // RVCT 2, ARM v6
-            case 11: // RVCT GNUPOC
-            case 12: // RVCT 4, ARM v5
-            case 13: // RVCT 4, ARM v6
-                abi = Abi(Abi::ARM, Abi::Symbian,
-                                           Abi::Symbian_device,
-                                           Abi::Format_ELF,
-                                           32).toString();
-                break;
-            case 9: // GCC Maemo5
-                abi = Abi(Abi::ARM, Abi::Linux,
-                                           Abi::Linux_maemo,
-                                           Abi::Format_ELF,
-                                           32).toString();
-
-                break;
-            case 14: // GCC Harmattan
-                abi = Abi(Abi::ARM, Abi::Linux,
-                                           Abi::Linux_harmattan,
-                                           Abi::Format_ELF,
-                                           32).toString();
-                break;
-            case 15: // GCC Meego
-                abi = Abi(Abi::ARM, Abi::Linux,
-                                           Abi::Linux_meego,
-                                           Abi::Format_ELF,
-                                           32).toString();
-                break;
-            default:
-                break;
-            }
-            if (abi.isEmpty() || m_abiToDebuggerMap.contains(abi))
-                continue;
-
-            m_abiToDebuggerMap.insert(abi, binary);
-        }
-    }
-
-    m_abiToDebuggerMapChanged = false;
-}
-
-void CommonOptionsPage::writeSettings() /* static */
-{
-    if (!m_abiToDebuggerMapChanged)
-        return;
-
-    QSettings *settings = Core::ICore::instance()->settings();
-
-    settings->beginWriteArray(DEBUGGER_MAPPING_ARRAY);
-
-    int index = 0;
-    for (QMap<QString, QString>::const_iterator i = m_abiToDebuggerMap.constBegin();
-         i != m_abiToDebuggerMap.constEnd(); ++i) {
-        if (i.value().isEmpty())
-            continue;
-
-        settings->setArrayIndex(index);
-        ++index;
-
-        settings->setValue(DEBUGGER_ABI_KEY, i.key());
-        settings->setValue(DEBUGGER_BINARY_KEY, i.value());
-    }
-    settings->endArray();
-
-    m_abiToDebuggerMapChanged = false;
-}
-
-void CommonOptionsPage::handleToolChainAdditions(ToolChain *tc)
-{
-    Abi tcAbi = tc->targetAbi();
-
-    if (tcAbi.binaryFormat() != Abi::Format_ELF
-            && tcAbi.binaryFormat() != Abi::Format_Mach_O
-            && !( tcAbi.os() == Abi::Windows
-                  && tcAbi.osFlavor() == Abi::Windows_msys ))
-        return;
-    if (m_abiToDebuggerMap.contains(tcAbi.toString()))
-        return;
-
-    QString binary;
-#ifdef Q_OS_UNIX
-    Abi hostAbi = Abi::hostAbi();
-    if (hostAbi == tcAbi)
-        binary = QLatin1String("gdb");
-#endif
-    m_abiToDebuggerMap.insert(tc->targetAbi().toString(), binary);
-}
-
-void CommonOptionsPage::handleToolChainRemovals(ToolChain *tc)
-{
-    QList<ToolChain *> tcs = ToolChainManager::instance()->toolChains();
-    foreach (ToolChain *current, tcs) {
-        if (current->targetAbi() == tc->targetAbi())
-            return;
-    }
-
-    m_abiToDebuggerMap.remove(tc->targetAbi().toString());
-}
-
-
 ///////////////////////////////////////////////////////////////////////
 //
 // DebuggingHelperOptionPage
diff --git a/src/plugins/debugger/commonoptionspage.h b/src/plugins/debugger/commonoptionspage.h
index 02e159f85e9..f975fd71116 100644
--- a/src/plugins/debugger/commonoptionspage.h
+++ b/src/plugins/debugger/commonoptionspage.h
@@ -69,18 +69,8 @@ public:
     void finish();
     bool matches(const QString &s) const;
 
-    void readSettings();
-    void writeSettings();
-    QString debuggerForAbi(const QString &abi) const;
-
-private slots:
-    void handleToolChainAdditions(ProjectExplorer::ToolChain *);
-    void handleToolChainRemovals(ProjectExplorer::ToolChain *);
-
 private:
     typedef QMap<QString, QString> AbiToDebuggerMap;
-    bool m_abiToDebuggerMapChanged;
-    AbiToDebuggerMap m_abiToDebuggerMap;
     Ui::CommonOptionsPage m_ui;
     Utils::SavedActionSet m_group;
     QString m_searchKeywords;
diff --git a/src/plugins/debugger/commonoptionspage.ui b/src/plugins/debugger/commonoptionspage.ui
index 9315c6d2599..3fb5ea321a9 100644
--- a/src/plugins/debugger/commonoptionspage.ui
+++ b/src/plugins/debugger/commonoptionspage.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>356</width>
-    <height>357</height>
+    <width>361</width>
+    <height>334</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -129,40 +129,24 @@
      </layout>
     </widget>
    </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox">
-     <property name="title">
-      <string>External Debuggers</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
-       <widget class="Debugger::Internal::DebuggerChooserWidget" name="debuggerChooserWidget" native="true"/>
-      </item>
-     </layout>
-    </widget>
-   </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::MinimumExpanding</enum>
+     </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>10</width>
-       <height>1</height>
+       <width>0</width>
+       <height>0</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
- <customwidgets>
-  <customwidget>
-   <class>Debugger::Internal::DebuggerChooserWidget</class>
-   <extends>QWidget</extends>
-   <header>debuggerchooserwidget.h</header>
-  </customwidget>
- </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 36103cf1d61..ef960c8910c 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -91,6 +91,7 @@
 #include <projectexplorer/project.h>
 #include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/session.h>
 #include <projectexplorer/target.h>
 
@@ -593,7 +594,6 @@ public slots:
     {
         m_debuggerSettings->writeSettings();
         m_mainWindow->writeSettings();
-        m_commonOptionsPage->writeSettings();
     }
 
     void selectThread(int index)
@@ -2367,7 +2367,12 @@ void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
 
 QString DebuggerPluginPrivate::debuggerForAbi(const Abi &abi) const
 {
-    return m_commonOptionsPage->debuggerForAbi(abi.toString());
+    foreach (const ToolChain *tc, ToolChainManager::instance()->findToolChains(abi)) {
+        const QString debugger = tc->debuggerCommand();
+        if (!debugger.isEmpty())
+            return debugger;
+    }
+    return QString();
 }
 
 DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
@@ -2591,7 +2596,6 @@ void DebuggerPluginPrivate::extensionsInitialized()
     m_plugin->addAutoReleasedObject(m_commonOptionsPage);
 
     m_debuggerSettings->readSettings();
-    m_commonOptionsPage->readSettings();
 
     // Do not fail to load the whole plugin if something goes wrong here.
     QString errorMessage;
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index b34f149ea66..e6bf504f1ca 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -248,6 +248,7 @@ GccToolChain::GccToolChain(const QString &id, bool autodetect) :
 GccToolChain::GccToolChain(const GccToolChain &tc) :
     ToolChain(tc),
     m_compilerPath(tc.compilerPath()),
+    m_debuggerCommand(tc.debuggerCommand()),
     m_forcedTo32Bit(tc.m_forcedTo32Bit),
     m_supports64Bit(tc.m_supports64Bit),
     m_targetAbi(tc.m_targetAbi)
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 0648d8c8eed..0cde858943b 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -41,14 +41,19 @@
 #include <utils/qtcprocess.h>
 #include <utils/qtcassert.h>
 #include <utils/synchronousprocess.h>
+#ifdef Q_OS_WIN
+#    include <utils/winutils.h>
+#endif
 
 #include <QtCore/QCoreApplication>
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 #include <QtCore/QSettings>
+#include <QtCore/QUrl>
 #include <QtCore/QTemporaryFile>
 #include <QtGui/QLabel>
 #include <QtGui/QFormLayout>
+#include <QtGui/QDesktopServices>
 
 static const char debuggerCommandKeyC[] = "ProjectExplorer.MsvcToolChain.Debugger";
 
@@ -411,6 +416,42 @@ ToolChain *MsvcToolChain::clone() const
     return new MsvcToolChain(*this);
 }
 
+// --------------------------------------------------------------------------
+// MsvcDebuggerConfigLabel
+// --------------------------------------------------------------------------
+
+static const char dgbToolsDownloadLink32C[] = "http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx";
+static const char dgbToolsDownloadLink64C[] = "http://www.microsoft.com/whdc/devtools/debugging/install64bit.Mspx";
+
+QString MsvcDebuggerConfigLabel::labelText()
+{
+#ifdef Q_OS_WIN
+    const bool is64bit = Utils::winIs64BitSystem();
+#else
+    const bool is64bit = false;
+#endif
+    const QString link = is64bit ? QLatin1String(dgbToolsDownloadLink64C) : QLatin1String(dgbToolsDownloadLink32C);
+    //: Label text for path configuration. %2 is "x-bit version".
+    return tr(
+    "<html><body><p>Specify the path to the "
+    "<a href=\"%1\">Windows Console Debugger executable</a>"
+    " (%2) here.</p>"
+    "</body></html>").arg(link, (is64bit ? tr("64-bit version")
+                                         : tr("32-bit version")));
+}
+
+MsvcDebuggerConfigLabel::MsvcDebuggerConfigLabel(QWidget *parent) :
+        QLabel(labelText(), parent)
+{
+    connect(this, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)));
+    setTextInteractionFlags(Qt::TextBrowserInteraction);
+}
+
+void MsvcDebuggerConfigLabel::slotLinkActivated(const QString &link)
+{
+    QDesktopServices::openUrl(QUrl(link));
+}
+
 // --------------------------------------------------------------------------
 // MsvcToolChainConfigWidget
 // --------------------------------------------------------------------------
@@ -420,6 +461,7 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) :
 {
     QFormLayout *formLayout = new QFormLayout(this);
     formLayout->addRow(new QLabel(tc->displayName()));
+    formLayout->addRow(new MsvcDebuggerConfigLabel);
     addDebuggerCommandControls(formLayout, QStringList(QLatin1String("-version")));
     addDebuggerAutoDetection(this, SLOT(autoDetectDebugger()));
     addErrorLabel(formLayout);
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index 32f023c9714..367a99d579d 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -39,6 +39,8 @@
 
 #include <utils/environment.h>
 
+#include <QtGui/QLabel>
+
 namespace ProjectExplorer {
 namespace Internal {
 
@@ -107,6 +109,23 @@ public:
     ToolChainConfigWidget *configurationWidget(ToolChain *);
 };
 
+// --------------------------------------------------------------------------
+// MsvcDebuggerConfigLabel: Label displaying debugging tools download info.
+// --------------------------------------------------------------------------
+
+class MsvcDebuggerConfigLabel : public QLabel
+{
+    Q_OBJECT
+public:
+    explicit MsvcDebuggerConfigLabel(QWidget *parent = 0);
+
+private slots:
+    void slotLinkActivated(const QString &l);
+
+private:
+    static QString labelText();
+};
+
 // --------------------------------------------------------------------------
 // MsvcToolChainConfigWidget
 // --------------------------------------------------------------------------
-- 
GitLab