toolchainmanager.cpp 8.67 KB
Newer Older
1 2 3 4 5 6
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
hjk's avatar
hjk committed
7
** Contact: Nokia Corporation (info@qt.nokia.com)
8 9 10 11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12 13 14 15 16 17
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 19
**
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
21 22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23 24 25 26 27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
28
** If you have questions regarding the use of this file, please contact
Tobias Hunger's avatar
Tobias Hunger committed
29
** Nokia at info@qt.nokia.com.
30 31 32 33
**
**************************************************************************/

#include "toolchainmanager.h"
34
#include "abi.h"
35 36
#include "toolchain.h"

Tobias Hunger's avatar
Tobias Hunger committed
37 38 39
#include <coreplugin/icore.h>
#include <projectexplorer/persistentsettings.h>

40 41 42
#include <extensionsystem/pluginmanager.h>

#include <QtCore/QCoreApplication>
43
#include <QtCore/QDir>
Tobias Hunger's avatar
Tobias Hunger committed
44
#include <QtCore/QSettings>
45
#include <QtGui/QMainWindow>
Tobias Hunger's avatar
Tobias Hunger committed
46

47 48 49 50 51 52 53
static const char TOOLCHAIN_DATA_KEY[] = "ToolChain.";
static const char TOOLCHAIN_COUNT_KEY[] = "ToolChain.Count";
static const char TOOLCHAIN_FILE_VERSION_KEY[] = "Version";
static const char DEFAULT_DEBUGGER_COUNT_KEY[] = "DefaultDebugger.Count";
static const char DEFAULT_DEBUGGER_ABI_KEY[] = "DefaultDebugger.Abi.";
static const char DEFAULT_DEBUGGER_PATH_KEY[] = "DefaultDebugger.Path.";
static const char TOOLCHAIN_FILENAME[] = "/toolChains.xml";
54

Tobias Hunger's avatar
Tobias Hunger committed
55 56 57 58
static QString settingsFileName()
{
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    QFileInfo settingsLocation(pm->settings()->fileName());
59
    return settingsLocation.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME);
Tobias Hunger's avatar
Tobias Hunger committed
60
}
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

namespace ProjectExplorer {

ToolChainManager *ToolChainManager::m_instance = 0;

namespace Internal {

// --------------------------------------------------------------------------
// ToolChainManagerPrivate
// --------------------------------------------------------------------------

class ToolChainManagerPrivate
{
public:
    QList<ToolChain *> m_toolChains;
76
    QMap<QString, QString> m_abiToDebugger;
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
};

} // namespace Internal

// --------------------------------------------------------------------------
// ToolChainManager
// --------------------------------------------------------------------------

ToolChainManager *ToolChainManager::instance()
{
    Q_ASSERT(m_instance);
    return m_instance;
}

ToolChainManager::ToolChainManager(QObject *parent) :
    QObject(parent),
    m_d(new Internal::ToolChainManagerPrivate)
{
    Q_ASSERT(!m_instance);
    m_instance = this;
Tobias Hunger's avatar
Tobias Hunger committed
97 98
    connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
            this, SLOT(saveToolChains()));
99 100 101 102 103 104
    connect(this, SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
            this, SIGNAL(toolChainsChanged()));
    connect(this, SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
            this, SIGNAL(toolChainsChanged()));
    connect(this, SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
            this, SIGNAL(toolChainsChanged()));
105 106 107 108
}

void ToolChainManager::restoreToolChains()
{
109 110 111 112 113
    // Restore SDK settings first
    restoreToolChains(Core::ICore::instance()->resourcePath()
                      + QLatin1String("/Nokia") + QLatin1String(TOOLCHAIN_FILENAME), true);

    // Then auto detect
Tobias Hunger's avatar
Tobias Hunger committed
114 115
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    QList<ToolChainFactory *> factories = pm->getObjects<ToolChainFactory>();
116
    // Autodetect tool chains:
117 118 119 120 121 122
    foreach (ToolChainFactory *f, factories) {
        QList<ToolChain *> tcs = f->autoDetect();
        foreach (ToolChain *tc, tcs)
            registerToolChain(tc);
    }

123
    // Then restore user settings
124 125 126 127 128
    restoreToolChains(settingsFileName(), false);
}

ToolChainManager::~ToolChainManager()
{
129
    // Deregister tool chains
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
    QList<ToolChain *> copy = m_d->m_toolChains;
    foreach (ToolChain *tc, copy)
        deregisterToolChain(tc);

    delete m_d;
    m_instance = 0;
}

void ToolChainManager::saveToolChains()
{
    PersistentSettingsWriter writer;
    writer.saveValue(QLatin1String(TOOLCHAIN_FILE_VERSION_KEY), 1);

    int count = 0;
    foreach (ToolChain *tc, m_d->m_toolChains) {
        if (!tc->isAutoDetected() && tc->isValid()) {
            QVariantMap tmp = tc->toMap();
            if (tmp.isEmpty())
                continue;
            writer.saveValue(QString::fromLatin1(TOOLCHAIN_DATA_KEY) + QString::number(count), tmp);
            ++count;
        }
    }
    writer.saveValue(QLatin1String(TOOLCHAIN_COUNT_KEY), count);
154
    writer.save(settingsFileName(), "QtCreatorToolChains", Core::ICore::instance()->mainWindow());
155 156

    // Do not save default debuggers! Those are set by the SDK!
157 158 159 160
}

void ToolChainManager::restoreToolChains(const QString &fileName, bool autoDetected)
{
Tobias Hunger's avatar
Tobias Hunger committed
161 162 163 164 165 166 167 168
    PersistentSettingsReader reader;
    if (!reader.load(fileName))
        return;
    QVariantMap data = reader.restoreValues();

    // Check version:
    int version = data.value(QLatin1String(TOOLCHAIN_FILE_VERSION_KEY), 0).toInt();
    if (version < 1)
169 170
        return;

171 172 173 174 175 176 177
    // Read default debugger settings (if any)
    int count = data.value(QLatin1String(DEFAULT_DEBUGGER_COUNT_KEY)).toInt();
    for (int i = 0; i < count; ++i) {
        const QString abiKey = QString::fromLatin1(DEFAULT_DEBUGGER_ABI_KEY) + QString::number(i);
        if (!data.contains(abiKey))
            continue;
        const QString pathKey = QString::fromLatin1(DEFAULT_DEBUGGER_PATH_KEY) + QString::number(i);
Tobias Hunger's avatar
Tobias Hunger committed
178
        if (!data.contains(pathKey))
179 180 181 182
            continue;
        m_d->m_abiToDebugger.insert(data.value(abiKey).toString(), data.value(pathKey).toString());
    }

183 184 185
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    QList<ToolChainFactory *> factories = pm->getObjects<ToolChainFactory>();

186
    count = data.value(QLatin1String(TOOLCHAIN_COUNT_KEY), 0).toInt();
Tobias Hunger's avatar
Tobias Hunger committed
187 188 189 190 191 192 193
    for (int i = 0; i < count; ++i) {
        const QString key = QString::fromLatin1(TOOLCHAIN_DATA_KEY) + QString::number(i);
        if (!data.contains(key))
            break;

        const QVariantMap tcMap = data.value(key).toMap();

194
        bool restored = false;
195
        foreach (ToolChainFactory *f, factories) {
Tobias Hunger's avatar
Tobias Hunger committed
196 197
            if (f->canRestore(tcMap)) {
                if (ToolChain *tc = f->restore(tcMap)) {
198 199
                    tc->setAutoDetected(autoDetected);

200 201 202 203 204
                    registerToolChain(tc);
                    restored = true;
                    break;
                }
            }
205
        }
206
        if (!restored)
207
            qWarning("Warning: Unable to restore manual tool chain '%s' stored in %s.",
Tobias Hunger's avatar
Tobias Hunger committed
208 209
                     qPrintable(ToolChainFactory::idFromMap(tcMap)),
                     qPrintable(QDir::toNativeSeparators(fileName)));
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    }
}

QList<ToolChain *> ToolChainManager::toolChains() const
{
    return m_d->m_toolChains;
}

QList<ToolChain *> ToolChainManager::findToolChains(const Abi &abi) const
{
    QList<ToolChain *> result;
    foreach (ToolChain *tc, m_d->m_toolChains) {
        Abi targetAbi = tc->targetAbi();
        if (targetAbi.isCompatibleWith(abi))
            result.append(tc);
    }
    return result;
}

ToolChain *ToolChainManager::findToolChain(const QString &id) const
{
    foreach (ToolChain *tc, m_d->m_toolChains) {
        if (tc->id() == id)
            return tc;
    }
    return 0;
}

238 239 240 241 242
QString ToolChainManager::defaultDebugger(const Abi &abi) const
{
    return m_d->m_abiToDebugger.value(abi.toString());
}

Tobias Hunger's avatar
Tobias Hunger committed
243 244 245 246 247 248 249
void ToolChainManager::notifyAboutUpdate(ProjectExplorer::ToolChain *tc)
{
    if (!tc || !m_d->m_toolChains.contains(tc))
        return;
    emit toolChainUpdated(tc);
}

250
bool ToolChainManager::registerToolChain(ToolChain *tc)
251 252
{
    if (!tc || m_d->m_toolChains.contains(tc))
253
        return true;
254 255
    foreach (ToolChain *current, m_d->m_toolChains) {
        if (*tc == *current)
256
            return false;
257 258 259 260
    }

    m_d->m_toolChains.append(tc);
    emit toolChainAdded(tc);
261
    return true;
262 263 264 265 266 267 268 269 270 271 272 273
}

void ToolChainManager::deregisterToolChain(ToolChain *tc)
{
    if (!tc || !m_d->m_toolChains.contains(tc))
        return;
    m_d->m_toolChains.removeOne(tc);
    emit toolChainRemoved(tc);
    delete tc;
}

} // namespace ProjectExplorer