diff options
Diffstat (limited to 'src/plugins/qnx/qnxtoolchain.cpp')
-rw-r--r-- | src/plugins/qnx/qnxtoolchain.cpp | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp new file mode 100644 index 0000000000..e321c3557b --- /dev/null +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -0,0 +1,269 @@ +/************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** +** Contact: BlackBerry (qt@blackberry.com) +** Contact: KDAB (info@kdab.com) +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qnxtoolchain.h" +#include "qnxconstants.h" +#include "qnxutils.h" + +#include "blackberryconfigurationmanager.h" +#include "blackberryconfiguration.h" + +#include <utils/pathchooser.h> + +#include <QFormLayout> + +using namespace ProjectExplorer; +namespace Qnx { +namespace Internal { + +static const char CompilernNdkPath[] = "Qnx.QnxToolChain.NDKPath"; + +static const QList<Abi> qccSupportedAbis() +{ + QList<Abi> abis; + abis << Abi(Abi::ArmArchitecture, Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 32); + abis << Abi(Abi::X86Architecture, Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 32); + + return abis; +} + +static void setQnxEnvironment(Utils::Environment &env, const QList<Utils::EnvironmentItem> &qnxEnv) +{ + // We only need to set QNX_HOST and QNX_TARGET needed when running qcc + foreach (const Utils::EnvironmentItem &item, qnxEnv) { + if (item.name == QLatin1String("QNX_HOST") || + item.name == QLatin1String("QNX_TARGET") ) + env.set(item.name, item.value); + } +} + +QnxToolChain::QnxToolChain(ToolChain::Detection d) + : GccToolChain(QLatin1String(Constants::QNX_TOOLCHAIN_ID), d) +{ +} + +QString QnxToolChain::type() const +{ + return QLatin1String(Constants::QNX_TOOLCHAIN_ID); +} + +QString QnxToolChain::typeDisplayName() const +{ + return QnxToolChainFactory::tr("QCC"); +} + +ToolChainConfigWidget *QnxToolChain::configurationWidget() +{ + return new QnxToolChainConfigWidget(this); +} + +void QnxToolChain::addToEnvironment(Utils::Environment &env) const +{ + foreach (BlackBerryConfiguration* config, BlackBerryConfigurationManager::instance().configurations()) { + if (config->gccCompiler() == compilerCommand()) { + setQnxEnvironment(env, config->qnxEnv()); + break; + } + } + + if (env.value(QLatin1String("QNX_HOST")).isEmpty() + || env.value(QLatin1String("QNX_TARGET")).isEmpty()) + setQnxEnvironment(env, QnxUtils::qnxEnvironment(m_ndkPath)); + + GccToolChain::addToEnvironment(env); +} + +QList<Utils::FileName> QnxToolChain::suggestedMkspecList() const +{ + QList<Utils::FileName> mkspecList; + mkspecList << Utils::FileName::fromString(QLatin1String("qnx-armv7le-qcc")); + mkspecList << Utils::FileName::fromString(QLatin1String("qnx-x86-qcc")); + mkspecList << Utils::FileName::fromString(QLatin1String("blackberry-armv7le-qcc")); + mkspecList << Utils::FileName::fromString(QLatin1String("blackberry-x86-qcc")); + + return mkspecList; +} + +QVariantMap QnxToolChain::toMap() const +{ + QVariantMap data = GccToolChain::toMap(); + data.insert(QLatin1String(CompilernNdkPath), m_ndkPath); + return data; +} + +bool QnxToolChain::fromMap(const QVariantMap &data) +{ + if (!GccToolChain::fromMap(data)) + return false; + + m_ndkPath = data.value(QLatin1String(CompilernNdkPath)).toString(); + return true; +} + +QString QnxToolChain::ndkPath() const +{ + return m_ndkPath; +} + +void QnxToolChain::setNdkPath(const QString &ndkPath) +{ + m_ndkPath = ndkPath; +} + +// qcc doesn't support a "-dumpmachine" option to get supported abis +QList<Abi> QnxToolChain::detectSupportedAbis() const +{ + return qccSupportedAbis(); +} + +// Qcc is a multi-compiler driver, and most of the gcc options can be accomplished by using the -Wp, and -Wc +// options to pass the options directly down to the compiler +QStringList QnxToolChain::reinterpretOptions(const QStringList &args) const +{ + QStringList arguments; + foreach (const QString &str, args) { + if (str.startsWith(QLatin1String("--sysroot="))) + continue; + QString arg = str; + if (arg == QLatin1String("-v") + || arg == QLatin1String("-dM")) + arg.prepend(QLatin1String("-Wp,")); + arguments << arg; + } + + return arguments; +} + +// -------------------------------------------------------------------------- +// QnxToolChainFactory +// -------------------------------------------------------------------------- + +QnxToolChainFactory::QnxToolChainFactory() +{ + setId(Constants::QNX_TOOLCHAIN_ID); + setDisplayName(tr("QCC")); +} + +bool QnxToolChainFactory::canRestore(const QVariantMap &data) +{ + const QString id = idFromMap(data); + return id.startsWith(QLatin1String(Constants::QNX_TOOLCHAIN_ID) + QLatin1Char(':')); +} + +ToolChain *QnxToolChainFactory::restore(const QVariantMap &data) +{ + QnxToolChain *tc = new QnxToolChain(ToolChain::ManualDetection); + if (tc->fromMap(data)) + return tc; + + delete tc; + return 0; +} + +bool QnxToolChainFactory::canCreate() +{ + return true; +} + +ToolChain *QnxToolChainFactory::create() +{ + return new QnxToolChain(ToolChain::ManualDetection); +} + +//--------------------------------------------------------------------------------- +// QnxToolChainConfigWidget +//--------------------------------------------------------------------------------- + +QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc) + : ToolChainConfigWidget(tc) + , m_compilerCommand(new Utils::PathChooser) + , m_ndkPath(new Utils::PathChooser) + , m_abiWidget(new AbiWidget) +{ + m_compilerCommand->setExpectedKind(Utils::PathChooser::ExistingCommand); + m_compilerCommand->setFileName(tc->compilerCommand()); + m_compilerCommand->setEnabled(!tc->isAutoDetected()); + + m_ndkPath->setExpectedKind(Utils::PathChooser::ExistingDirectory); + m_ndkPath->setPath(tc->ndkPath()); + m_ndkPath->setEnabled(!tc->isAutoDetected()); + + m_abiWidget->setAbis(qccSupportedAbis(), tc->targetAbi()); + m_abiWidget->setEnabled(!tc->isAutoDetected()); + + m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand); + //: SDP refers to 'Software Development Platform'. + m_mainLayout->addRow(tr("NDK/SDP path:"), m_ndkPath); + m_mainLayout->addRow(tr("&ABI:"), m_abiWidget); + + connect(m_compilerCommand, SIGNAL(changed(QString)), this, SIGNAL(dirty())); + connect(m_ndkPath, SIGNAL(changed(QString)), this, SIGNAL(dirty())); + connect(m_abiWidget, SIGNAL(abiChanged()), this, SIGNAL(dirty())); +} + +void QnxToolChainConfigWidget::applyImpl() +{ + if (toolChain()->isAutoDetected()) + return; + + QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain()); + Q_ASSERT(tc); + QString displayName = tc->displayName(); + tc->setCompilerCommand(m_compilerCommand->fileName()); + tc->setDisplayName(displayName); // reset display name + tc->setNdkPath(m_ndkPath->fileName().toString()); + tc->setTargetAbi(m_abiWidget->currentAbi()); +} + +void QnxToolChainConfigWidget::discardImpl() +{ + // subwidgets are not yet connected! + bool blocked = blockSignals(true); + QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain()); + m_compilerCommand->setFileName(tc->compilerCommand()); + m_ndkPath->setPath(tc->ndkPath()); + m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi()); + if (!m_compilerCommand->path().isEmpty()) + m_abiWidget->setEnabled(true); + blockSignals(blocked); +} + +bool QnxToolChainConfigWidget::isDirtyImpl() const +{ + QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain()); + Q_ASSERT(tc); + return m_compilerCommand->fileName() != tc->compilerCommand() + || m_ndkPath->path() != tc->ndkPath() + || m_abiWidget->currentAbi() != tc->targetAbi(); +} + +} // namespace Internal +} // namespace Qnx |