2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2022 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
2022-02-01 14:30:35 +01:00
|
|
|
|
|
|
|
|
#include "mcupackage.h"
|
2022-03-23 13:24:02 +01:00
|
|
|
#include "mcusupportversiondetection.h"
|
2022-04-22 11:41:33 +02:00
|
|
|
#include "settingshandler.h"
|
2022-02-01 14:30:35 +01:00
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
#include <baremetal/baremetalconstants.h>
|
2022-02-01 14:30:35 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2022-03-23 13:24:02 +01:00
|
|
|
#include <debugger/debuggeritem.h>
|
|
|
|
|
#include <debugger/debuggeritemmanager.h>
|
|
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
|
|
|
|
#include <projectexplorer/toolchain.h>
|
|
|
|
|
#include <projectexplorer/toolchainmanager.h>
|
2022-02-21 15:24:46 +01:00
|
|
|
#include <utils/algorithm.h>
|
2022-08-24 14:57:06 +02:00
|
|
|
#include <utils/environment.h>
|
2022-02-01 14:30:35 +01:00
|
|
|
#include <utils/infolabel.h>
|
|
|
|
|
#include <utils/pathchooser.h>
|
|
|
|
|
#include <utils/utilsicons.h>
|
|
|
|
|
|
|
|
|
|
#include <QDesktopServices>
|
|
|
|
|
#include <QGridLayout>
|
|
|
|
|
#include <QToolButton>
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
using namespace ProjectExplorer;
|
2022-02-01 14:30:35 +01:00
|
|
|
using namespace Utils;
|
|
|
|
|
|
2022-02-15 14:35:35 +01:00
|
|
|
namespace McuSupport::Internal {
|
2022-02-01 14:30:35 +01:00
|
|
|
|
2022-04-22 11:41:33 +02:00
|
|
|
McuPackage::McuPackage(const SettingsHandler::Ptr &settingsHandler,
|
|
|
|
|
const QString &label,
|
2022-02-15 11:18:56 +01:00
|
|
|
const FilePath &defaultPath,
|
2022-02-21 15:24:46 +01:00
|
|
|
const FilePath &detectionPath,
|
2022-02-15 11:18:56 +01:00
|
|
|
const QString &settingsKey,
|
2022-02-22 13:36:55 +01:00
|
|
|
const QString &cmakeVarName,
|
2022-02-15 11:18:56 +01:00
|
|
|
const QString &envVarName,
|
2022-06-07 20:58:42 +02:00
|
|
|
const QStringList &versions,
|
2022-02-15 11:18:56 +01:00
|
|
|
const QString &downloadUrl,
|
2022-02-21 15:24:46 +01:00
|
|
|
const McuPackageVersionDetector *versionDetector,
|
2022-09-27 23:10:46 +02:00
|
|
|
const bool addToSystemPath)
|
2022-04-22 11:41:33 +02:00
|
|
|
: settingsHandler(settingsHandler)
|
|
|
|
|
, m_label(label)
|
|
|
|
|
, m_defaultPath(settingsHandler->getPath(settingsKey, QSettings::SystemScope, defaultPath))
|
2022-02-01 14:30:35 +01:00
|
|
|
, m_detectionPath(detectionPath)
|
|
|
|
|
, m_settingsKey(settingsKey)
|
|
|
|
|
, m_versionDetector(versionDetector)
|
2022-06-07 20:58:42 +02:00
|
|
|
, m_versions(versions)
|
2022-02-22 13:36:55 +01:00
|
|
|
, m_cmakeVariableName(cmakeVarName)
|
2022-02-01 16:07:50 +01:00
|
|
|
, m_environmentVariableName(envVarName)
|
|
|
|
|
, m_downloadUrl(downloadUrl)
|
2022-02-21 15:24:46 +01:00
|
|
|
, m_addToSystemPath(addToSystemPath)
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
2022-08-24 14:57:06 +02:00
|
|
|
m_path = FilePath::fromUserInput(qtcEnvironmentVariable(m_environmentVariableName));
|
2022-07-14 15:44:54 +02:00
|
|
|
if (!m_path.exists()) {
|
|
|
|
|
m_path = this->settingsHandler->getPath(settingsKey, QSettings::UserScope, m_defaultPath);
|
|
|
|
|
}
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString McuPackage::label() const
|
|
|
|
|
{
|
|
|
|
|
return m_label;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-01 22:35:33 +01:00
|
|
|
QString McuPackage::settingsKey() const
|
|
|
|
|
{
|
|
|
|
|
return m_settingsKey;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-23 13:24:02 +01:00
|
|
|
QString McuPackage::cmakeVariableName() const
|
2022-02-22 13:36:55 +01:00
|
|
|
{
|
|
|
|
|
return m_cmakeVariableName;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-23 13:24:02 +01:00
|
|
|
QString McuPackage::environmentVariableName() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
|
|
|
|
return m_environmentVariableName;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
bool McuPackage::isAddToSystemPath() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
2022-02-21 15:24:46 +01:00
|
|
|
return m_addToSystemPath;
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-07 20:58:42 +02:00
|
|
|
QStringList McuPackage::versions() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
2022-06-07 20:58:42 +02:00
|
|
|
return m_versions;
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-07-04 22:30:42 +02:00
|
|
|
const McuPackageVersionDetector *McuPackage::getVersionDetector() const
|
|
|
|
|
{
|
|
|
|
|
return m_versionDetector.get();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
FilePath McuPackage::basePath() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
2022-02-21 15:24:46 +01:00
|
|
|
return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path;
|
|
|
|
|
}
|
2022-02-01 14:30:35 +01:00
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
FilePath McuPackage::path() const
|
|
|
|
|
{
|
2022-09-27 23:10:46 +02:00
|
|
|
return basePath().cleanPath();
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
FilePath McuPackage::defaultPath() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
2022-07-14 15:44:54 +02:00
|
|
|
return m_defaultPath.cleanPath();
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
FilePath McuPackage::detectionPath() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
2022-02-21 15:24:46 +01:00
|
|
|
return m_detectionPath;
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-08-09 10:56:33 +02:00
|
|
|
void McuPackage::setPath(const FilePath &newPath)
|
|
|
|
|
{
|
|
|
|
|
m_path = newPath;
|
|
|
|
|
updateStatus();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-01 14:30:35 +01:00
|
|
|
void McuPackage::updatePath()
|
|
|
|
|
{
|
2022-02-15 11:18:56 +01:00
|
|
|
m_path = m_fileChooser->rawFilePath();
|
|
|
|
|
m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath);
|
|
|
|
|
updateStatus();
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void McuPackage::updateStatus()
|
|
|
|
|
{
|
|
|
|
|
bool validPath = !m_path.isEmpty() && m_path.exists();
|
2022-04-21 12:27:51 +02:00
|
|
|
const FilePath detectionPath = basePath() / m_detectionPath.path();
|
2022-02-01 14:30:35 +01:00
|
|
|
const bool validPackage = m_detectionPath.isEmpty() || detectionPath.exists();
|
|
|
|
|
m_detectedVersion = validPath && validPackage && m_versionDetector
|
2022-04-21 12:27:51 +02:00
|
|
|
? m_versionDetector->parseVersion(basePath())
|
2022-02-15 11:18:56 +01:00
|
|
|
: QString();
|
|
|
|
|
const bool validVersion = m_detectedVersion.isEmpty() || m_versions.isEmpty()
|
|
|
|
|
|| m_versions.contains(m_detectedVersion);
|
2022-02-01 14:30:35 +01:00
|
|
|
|
2022-02-15 11:18:56 +01:00
|
|
|
m_status = validPath ? (validPackage ? (validVersion ? Status::ValidPackage
|
|
|
|
|
: Status::ValidPackageMismatchedVersion)
|
|
|
|
|
: Status::ValidPathInvalidPackage)
|
|
|
|
|
: m_path.isEmpty() ? Status::EmptyPath
|
|
|
|
|
: Status::InvalidPath;
|
2022-02-01 14:30:35 +01:00
|
|
|
|
|
|
|
|
emit statusChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
McuPackage::Status McuPackage::status() const
|
|
|
|
|
{
|
|
|
|
|
return m_status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool McuPackage::isValidStatus() const
|
|
|
|
|
{
|
|
|
|
|
return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-01 14:30:35 +01:00
|
|
|
void McuPackage::updateStatusUi()
|
|
|
|
|
{
|
|
|
|
|
switch (m_status) {
|
2022-02-15 11:18:56 +01:00
|
|
|
case Status::ValidPackage:
|
|
|
|
|
m_infoLabel->setType(InfoLabel::Ok);
|
|
|
|
|
break;
|
|
|
|
|
case Status::ValidPackageMismatchedVersion:
|
|
|
|
|
m_infoLabel->setType(InfoLabel::Warning);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
m_infoLabel->setType(InfoLabel::NotOk);
|
|
|
|
|
break;
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
m_infoLabel->setText(statusText());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString McuPackage::statusText() const
|
|
|
|
|
{
|
|
|
|
|
const QString displayPackagePath = m_path.toUserOutput();
|
|
|
|
|
const QString displayVersions = m_versions.join(" or ");
|
2022-02-21 15:24:46 +01:00
|
|
|
const QString outDetectionPath = m_detectionPath.toUserOutput();
|
2022-02-15 11:18:56 +01:00
|
|
|
const QString displayRequiredPath = m_versions.empty() ? outDetectionPath
|
|
|
|
|
: QString("%1 %2").arg(outDetectionPath,
|
|
|
|
|
displayVersions);
|
|
|
|
|
const QString displayDetectedPath = m_versions.empty()
|
|
|
|
|
? outDetectionPath
|
|
|
|
|
: QString("%1 %2").arg(outDetectionPath,
|
|
|
|
|
m_detectedVersion);
|
2022-02-01 14:30:35 +01:00
|
|
|
|
|
|
|
|
QString response;
|
|
|
|
|
switch (m_status) {
|
2022-02-15 14:35:35 +01:00
|
|
|
case Status::ValidPackage:
|
2022-02-01 14:30:35 +01:00
|
|
|
response = m_detectionPath.isEmpty()
|
2022-02-15 11:18:56 +01:00
|
|
|
? (m_detectedVersion.isEmpty()
|
|
|
|
|
? tr("Path %1 exists.").arg(displayPackagePath)
|
|
|
|
|
: tr("Path %1 exists. Version %2 was found.")
|
|
|
|
|
.arg(displayPackagePath, m_detectedVersion))
|
|
|
|
|
: tr("Path %1 is valid, %2 was found.")
|
|
|
|
|
.arg(displayPackagePath, displayDetectedPath);
|
2022-02-01 14:30:35 +01:00
|
|
|
break;
|
2022-02-15 14:35:35 +01:00
|
|
|
case Status::ValidPackageMismatchedVersion: {
|
2022-02-15 11:18:56 +01:00
|
|
|
const QString versionWarning
|
|
|
|
|
= m_versions.size() == 1
|
|
|
|
|
? tr("but only version %1 is supported").arg(m_versions.first())
|
|
|
|
|
: tr("but only versions %1 are supported").arg(displayVersions);
|
2022-02-01 14:30:35 +01:00
|
|
|
response = tr("Path %1 is valid, %2 was found, %3.")
|
2022-02-15 11:18:56 +01:00
|
|
|
.arg(displayPackagePath, displayDetectedPath, versionWarning);
|
2022-02-01 14:30:35 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2022-02-15 14:35:35 +01:00
|
|
|
case Status::ValidPathInvalidPackage:
|
2022-02-01 14:30:35 +01:00
|
|
|
response = tr("Path %1 exists, but does not contain %2.")
|
2022-02-15 11:18:56 +01:00
|
|
|
.arg(displayPackagePath, displayRequiredPath);
|
2022-02-01 14:30:35 +01:00
|
|
|
break;
|
2022-02-15 14:35:35 +01:00
|
|
|
case Status::InvalidPath:
|
2022-02-01 14:30:35 +01:00
|
|
|
response = tr("Path %1 does not exist.").arg(displayPackagePath);
|
|
|
|
|
break;
|
2022-02-15 14:35:35 +01:00
|
|
|
case Status::EmptyPath:
|
2022-02-01 14:30:35 +01:00
|
|
|
response = m_detectionPath.isEmpty()
|
2022-02-15 11:18:56 +01:00
|
|
|
? tr("Path is empty.")
|
|
|
|
|
: tr("Path is empty, %1 not found.").arg(displayRequiredPath);
|
2022-02-01 14:30:35 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
bool McuPackage::writeToSettings() const
|
|
|
|
|
{
|
2022-04-22 11:41:33 +02:00
|
|
|
return settingsHandler->write(m_settingsKey, m_path, m_defaultPath);
|
2022-02-21 15:24:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *McuPackage::widget()
|
|
|
|
|
{
|
2022-03-28 16:42:51 +02:00
|
|
|
auto *widget = new QWidget;
|
2022-02-21 15:24:46 +01:00
|
|
|
m_fileChooser = new PathChooser;
|
|
|
|
|
m_fileChooser->lineEdit()->setButtonIcon(FancyLineEdit::Right, Icons::RESET.icon());
|
|
|
|
|
m_fileChooser->lineEdit()->setButtonVisible(FancyLineEdit::Right, true);
|
|
|
|
|
connect(m_fileChooser->lineEdit(), &FancyLineEdit::rightButtonClicked, this, [&] {
|
|
|
|
|
m_fileChooser->setFilePath(m_defaultPath);
|
|
|
|
|
});
|
|
|
|
|
|
2022-03-28 16:42:51 +02:00
|
|
|
auto layout = new QGridLayout(widget);
|
2022-02-21 15:24:46 +01:00
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
m_infoLabel = new InfoLabel();
|
|
|
|
|
|
|
|
|
|
if (!m_downloadUrl.isEmpty()) {
|
|
|
|
|
auto downLoadButton = new QToolButton;
|
|
|
|
|
downLoadButton->setIcon(Icons::ONLINE.icon());
|
|
|
|
|
downLoadButton->setToolTip(tr("Download from \"%1\"").arg(m_downloadUrl));
|
|
|
|
|
QObject::connect(downLoadButton, &QToolButton::pressed, this, [this] {
|
|
|
|
|
QDesktopServices::openUrl(m_downloadUrl);
|
|
|
|
|
});
|
|
|
|
|
layout->addWidget(downLoadButton, 0, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
layout->addWidget(m_fileChooser, 0, 0, 1, 2);
|
|
|
|
|
layout->addWidget(m_infoLabel, 1, 0, 1, -1);
|
|
|
|
|
|
|
|
|
|
m_fileChooser->setFilePath(m_path);
|
|
|
|
|
|
|
|
|
|
QObject::connect(this, &McuPackage::statusChanged, this, [this] { updateStatusUi(); });
|
|
|
|
|
|
2022-09-02 11:49:36 +02:00
|
|
|
QObject::connect(m_fileChooser, &PathChooser::textChanged, this, [this] {
|
2022-02-21 15:24:46 +01:00
|
|
|
updatePath();
|
|
|
|
|
emit changed();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
updateStatus();
|
2022-03-28 16:42:51 +02:00
|
|
|
return widget;
|
2022-02-21 15:24:46 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-22 11:41:33 +02:00
|
|
|
McuToolChainPackage::McuToolChainPackage(const SettingsHandler::Ptr &settingsHandler,
|
|
|
|
|
const QString &label,
|
2022-02-01 14:30:35 +01:00
|
|
|
const FilePath &defaultPath,
|
2022-02-21 15:24:46 +01:00
|
|
|
const FilePath &detectionPath,
|
2022-02-01 14:30:35 +01:00
|
|
|
const QString &settingsKey,
|
2022-02-21 15:24:46 +01:00
|
|
|
McuToolChainPackage::ToolChainType type,
|
2022-06-07 20:58:42 +02:00
|
|
|
const QStringList &versions,
|
2022-02-22 13:36:55 +01:00
|
|
|
const QString &cmakeVarName,
|
2022-02-15 11:18:56 +01:00
|
|
|
const QString &envVarName,
|
2022-02-01 14:30:35 +01:00
|
|
|
const McuPackageVersionDetector *versionDetector)
|
2022-04-22 11:41:33 +02:00
|
|
|
: McuPackage(settingsHandler,
|
|
|
|
|
label,
|
2022-03-23 13:24:02 +01:00
|
|
|
defaultPath,
|
|
|
|
|
detectionPath,
|
|
|
|
|
settingsKey,
|
|
|
|
|
cmakeVarName,
|
|
|
|
|
envVarName,
|
2022-06-07 20:58:42 +02:00
|
|
|
versions,
|
|
|
|
|
{}, // url
|
2022-03-23 13:24:02 +01:00
|
|
|
versionDetector)
|
2022-02-01 14:30:35 +01:00
|
|
|
, m_type(type)
|
2022-02-15 11:18:56 +01:00
|
|
|
{}
|
2022-02-01 14:30:35 +01:00
|
|
|
|
2022-02-21 15:24:46 +01:00
|
|
|
McuToolChainPackage::ToolChainType McuToolChainPackage::toolchainType() const
|
2022-02-01 14:30:35 +01:00
|
|
|
{
|
|
|
|
|
return m_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool McuToolChainPackage::isDesktopToolchain() const
|
|
|
|
|
{
|
2022-02-21 15:24:46 +01:00
|
|
|
return m_type == ToolChainType::MSVC || m_type == ToolChainType::GCC;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-20 17:51:59 +03:00
|
|
|
ToolChain *McuToolChainPackage::msvcToolChain(Id language)
|
2022-02-21 15:24:46 +01:00
|
|
|
{
|
|
|
|
|
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
|
|
|
|
|
const Abi abi = t->targetAbi();
|
|
|
|
|
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
|
|
|
|
|
return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor
|
|
|
|
|
|| abi.osFlavor() == Abi::WindowsMsvc2019Flavor)
|
|
|
|
|
&& abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64
|
|
|
|
|
&& t->language() == language;
|
|
|
|
|
});
|
|
|
|
|
return toolChain;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-20 17:51:59 +03:00
|
|
|
ToolChain *McuToolChainPackage::gccToolChain(Id language)
|
2022-02-21 15:24:46 +01:00
|
|
|
{
|
|
|
|
|
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
|
|
|
|
|
const Abi abi = t->targetAbi();
|
|
|
|
|
return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture
|
|
|
|
|
&& abi.wordWidth() == 64 && t->language() == language;
|
|
|
|
|
});
|
|
|
|
|
return toolChain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ToolChain *armGccToolChain(const FilePath &path, Id language)
|
|
|
|
|
{
|
|
|
|
|
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) {
|
|
|
|
|
return t->compilerCommand() == path && t->language() == language;
|
|
|
|
|
});
|
|
|
|
|
if (!toolChain) {
|
|
|
|
|
ToolChainFactory *gccFactory
|
|
|
|
|
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
|
|
|
|
|
[](ToolChainFactory *f) {
|
|
|
|
|
return f->supportedToolChainType()
|
|
|
|
|
== ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
|
|
|
|
|
});
|
|
|
|
|
if (gccFactory) {
|
|
|
|
|
const QList<ToolChain *> detected = gccFactory->detectForImport({path, language});
|
|
|
|
|
if (!detected.isEmpty()) {
|
|
|
|
|
toolChain = detected.first();
|
|
|
|
|
toolChain->setDetection(ToolChain::ManualDetection);
|
|
|
|
|
toolChain->setDisplayName("Arm GCC");
|
|
|
|
|
ToolChainManager::registerToolChain(toolChain);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return toolChain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ToolChain *iarToolChain(const FilePath &path, Id language)
|
|
|
|
|
{
|
|
|
|
|
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
|
|
|
|
|
return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID
|
|
|
|
|
&& t->language() == language;
|
|
|
|
|
});
|
|
|
|
|
if (!toolChain) {
|
|
|
|
|
ToolChainFactory *iarFactory
|
|
|
|
|
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
|
|
|
|
|
[](ToolChainFactory *f) {
|
|
|
|
|
return f->supportedToolChainType()
|
|
|
|
|
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
|
|
|
|
|
});
|
|
|
|
|
if (iarFactory) {
|
2022-03-14 16:37:57 +01:00
|
|
|
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}, {}));
|
2022-02-21 15:24:46 +01:00
|
|
|
if (detected.isEmpty())
|
|
|
|
|
detected = iarFactory->detectForImport({path, language});
|
|
|
|
|
for (auto tc : detected) {
|
|
|
|
|
if (tc->language() == language) {
|
|
|
|
|
toolChain = tc;
|
|
|
|
|
toolChain->setDetection(ToolChain::ManualDetection);
|
|
|
|
|
toolChain->setDisplayName("IAREW");
|
|
|
|
|
ToolChainManager::registerToolChain(toolChain);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return toolChain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ToolChain *McuToolChainPackage::toolChain(Id language) const
|
|
|
|
|
{
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
case ToolChainType::MSVC:
|
|
|
|
|
return msvcToolChain(language);
|
|
|
|
|
case ToolChainType::GCC:
|
|
|
|
|
return gccToolChain(language);
|
|
|
|
|
case ToolChainType::IAR: {
|
2022-04-21 12:27:51 +02:00
|
|
|
const FilePath compiler = (path() / "/bin/iccarm").withExecutableSuffix();
|
2022-02-21 15:24:46 +01:00
|
|
|
return iarToolChain(compiler, language);
|
|
|
|
|
}
|
|
|
|
|
case ToolChainType::ArmGcc:
|
|
|
|
|
case ToolChainType::KEIL:
|
|
|
|
|
case ToolChainType::GHS:
|
|
|
|
|
case ToolChainType::GHSArm:
|
|
|
|
|
case ToolChainType::Unsupported: {
|
|
|
|
|
const QLatin1String compilerName(
|
|
|
|
|
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
|
|
|
|
|
const QString comp = QLatin1String(m_type == ToolChainType::ArmGcc ? "/bin/arm-none-eabi-%1"
|
2022-03-23 13:24:02 +01:00
|
|
|
: "/bar/foo-keil-%1")
|
2022-02-21 15:24:46 +01:00
|
|
|
.arg(compilerName);
|
2022-04-21 12:27:51 +02:00
|
|
|
const FilePath compiler = (path() / comp).withExecutableSuffix();
|
2022-02-21 15:24:46 +01:00
|
|
|
|
|
|
|
|
return armGccToolChain(compiler, language);
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
Q_UNREACHABLE();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString McuToolChainPackage::toolChainName() const
|
|
|
|
|
{
|
|
|
|
|
switch (m_type) {
|
2022-06-20 17:51:59 +03:00
|
|
|
case ToolChainType::MSVC:
|
|
|
|
|
return QLatin1String("msvc");
|
|
|
|
|
case ToolChainType::GCC:
|
|
|
|
|
return QLatin1String("gcc");
|
2022-02-21 15:24:46 +01:00
|
|
|
case ToolChainType::ArmGcc:
|
|
|
|
|
return QLatin1String("armgcc");
|
|
|
|
|
case ToolChainType::IAR:
|
|
|
|
|
return QLatin1String("iar");
|
|
|
|
|
case ToolChainType::KEIL:
|
|
|
|
|
return QLatin1String("keil");
|
|
|
|
|
case ToolChainType::GHS:
|
|
|
|
|
return QLatin1String("ghs");
|
|
|
|
|
case ToolChainType::GHSArm:
|
|
|
|
|
return QLatin1String("ghs-arm");
|
|
|
|
|
default:
|
|
|
|
|
return QLatin1String("unsupported");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant McuToolChainPackage::debuggerId() const
|
|
|
|
|
{
|
|
|
|
|
using namespace Debugger;
|
|
|
|
|
|
|
|
|
|
QString sub, displayName;
|
|
|
|
|
DebuggerEngineType engineType;
|
|
|
|
|
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
case ToolChainType::ArmGcc: {
|
|
|
|
|
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
|
|
|
|
|
displayName = McuPackage::tr("Arm GDB at %1");
|
|
|
|
|
engineType = Debugger::GdbEngineType;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ToolChainType::IAR: {
|
|
|
|
|
sub = QString::fromLatin1("../common/bin/CSpyBat");
|
|
|
|
|
displayName = QLatin1String("CSpy");
|
|
|
|
|
engineType = Debugger::NoEngineType; // support for IAR missing
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ToolChainType::KEIL: {
|
|
|
|
|
sub = QString::fromLatin1("UV4/UV4");
|
|
|
|
|
displayName = QLatin1String("KEIL uVision Debugger");
|
|
|
|
|
engineType = Debugger::UvscEngineType;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-21 12:27:51 +02:00
|
|
|
const FilePath command = (path() / sub).withExecutableSuffix();
|
2022-02-21 15:24:46 +01:00
|
|
|
if (const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command)) {
|
|
|
|
|
return debugger->id();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebuggerItem newDebugger;
|
|
|
|
|
newDebugger.setCommand(command);
|
|
|
|
|
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
|
|
|
|
|
newDebugger.setEngineType(engineType);
|
|
|
|
|
return DebuggerItemManager::registerDebugger(newDebugger);
|
2022-02-01 14:30:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-02-15 11:18:56 +01:00
|
|
|
} // namespace McuSupport::Internal
|