McuSupport: refactor McuPackage

rename 'type' to 'toolChainType' in McuToolChainPackage
'addToPath' and 'relativePath' set in McuPackage constructor
put McuToolChainPackage methods together in same source file
'detectionPath' type changed from QString to FilePath
renamed boolean getters

Task-number: QTCREATORBUG-26897
Change-Id: If59c299901a169d08efa8f39614ef7c6d48d44ed
Reviewed-by: Piotr Mućko <piotr.mucko@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Christiaan Janssen
2022-02-21 15:24:46 +01:00
parent ec80ae2322
commit 7d9bb3f7e8
12 changed files with 461 additions and 459 deletions

View File

@@ -45,22 +45,22 @@ public:
ValidPackage ValidPackage
}; };
virtual QString label() const = 0;
virtual const QString &environmentVariableName() const = 0;
virtual bool isAddToSystemPath() const = 0;
virtual void setVersions(const QStringList &) = 0;
virtual Utils::FilePath basePath() const = 0; virtual Utils::FilePath basePath() const = 0;
virtual Utils::FilePath path() const = 0; virtual Utils::FilePath path() const = 0;
virtual QString label() const = 0;
virtual Utils::FilePath defaultPath() const = 0; virtual Utils::FilePath defaultPath() const = 0;
virtual QString detectionPath() const = 0; virtual Utils::FilePath detectionPath() const = 0;
virtual QString statusText() const = 0;
virtual void updateStatus() = 0;
virtual void updateStatus() = 0;
virtual Status status() const = 0; virtual Status status() const = 0;
virtual bool validStatus() const = 0; virtual QString statusText() const = 0;
virtual const QString &environmentVariableName() const = 0; virtual bool isValidStatus() const = 0;
virtual void setAddToPath(bool) = 0;
virtual bool addToPath() const = 0;
virtual bool writeToSettings() const = 0; virtual bool writeToSettings() const = 0;
virtual void setRelativePathModifier(const QString &) = 0;
virtual void setVersions(const QStringList &) = 0;
virtual QWidget *widget() = 0; virtual QWidget *widget() = 0;

View File

@@ -68,19 +68,19 @@ static FilePath qulDocsDir()
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{ {
switch (tcPackage->type()) { switch (tcPackage->toolchainType()) {
case McuToolChainPackage::Type::Unsupported: case McuToolChainPackage::ToolChainType::Unsupported:
return; return;
case McuToolChainPackage::Type::GHS: case McuToolChainPackage::ToolChainType::GHS:
case McuToolChainPackage::Type::GHSArm: case McuToolChainPackage::ToolChainType::GHSArm:
return; // No Green Hills toolchain, because support for it is missing. return; // No Green Hills toolchain, because support for it is missing.
case McuToolChainPackage::Type::IAR: case McuToolChainPackage::ToolChainType::IAR:
case McuToolChainPackage::Type::KEIL: case McuToolChainPackage::ToolChainType::KEIL:
case McuToolChainPackage::Type::MSVC: case McuToolChainPackage::ToolChainType::MSVC:
case McuToolChainPackage::Type::GCC: case McuToolChainPackage::ToolChainType::GCC:
case McuToolChainPackage::Type::ArmGcc: case McuToolChainPackage::ToolChainType::ArmGcc:
ToolChainKitAspect::setToolChain(k, ToolChainKitAspect::setToolChain(k,
tcPackage->toolChain( tcPackage->toolChain(
ProjectExplorer::Constants::C_LANGUAGE_ID)); ProjectExplorer::Constants::C_LANGUAGE_ID));
@@ -136,17 +136,17 @@ static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
return; return;
} }
switch (tcPackage->type()) { switch (tcPackage->toolchainType()) {
case McuToolChainPackage::Type::Unsupported: case McuToolChainPackage::ToolChainType::Unsupported:
case McuToolChainPackage::Type::GHS: case McuToolChainPackage::ToolChainType::GHS:
case McuToolChainPackage::Type::GHSArm: case McuToolChainPackage::ToolChainType::GHSArm:
case McuToolChainPackage::Type::IAR: case McuToolChainPackage::ToolChainType::IAR:
return; // No Green Hills and IAR debugger, because support for it is missing. return; // No Green Hills and IAR debugger, because support for it is missing.
case McuToolChainPackage::Type::KEIL: case McuToolChainPackage::ToolChainType::KEIL:
case McuToolChainPackage::Type::MSVC: case McuToolChainPackage::ToolChainType::MSVC:
case McuToolChainPackage::Type::GCC: case McuToolChainPackage::ToolChainType::GCC:
case McuToolChainPackage::Type::ArmGcc: { case McuToolChainPackage::ToolChainType::ArmGcc: {
const QVariant debuggerId = tcPackage->debuggerId(); const QVariant debuggerId = tcPackage->debuggerId();
if (debuggerId.isValid()) { if (debuggerId.isValid()) {
Debugger::DebuggerKitAspect::setDebugger(k, debuggerId); Debugger::DebuggerKitAspect::setDebugger(k, debuggerId);
@@ -182,7 +182,7 @@ static void setKitDependencies(Kit *k,
auto processPackage = [&dependencies](const McuAbstractPackage *package) { auto processPackage = [&dependencies](const McuAbstractPackage *package) {
if (!package->environmentVariableName().isEmpty()) if (!package->environmentVariableName().isEmpty())
dependencies.append({package->environmentVariableName(), dependencies.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->detectionPath())}); package->detectionPath().toUserOutput()});
}; };
for (auto package : mcuTarget->packages()) for (auto package : mcuTarget->packages())
processPackage(package); processPackage(package);
@@ -201,8 +201,8 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k); CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously // CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
if (mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHS if (mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHS
&& mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHSArm) { && mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHSArm) {
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}")); config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}")); config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
} }
@@ -240,8 +240,8 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
CMakeConfigurationKitAspect::setConfiguration(k, config); CMakeConfigurationKitAspect::setConfiguration(k, config);
if (HostOsInfo::isWindowsHost()) { if (HostOsInfo::isWindowsHost()) {
auto type = mcuTarget->toolChainPackage()->type(); auto type = mcuTarget->toolChainPackage()->toolchainType();
if (type == McuToolChainPackage::Type::GHS || type == McuToolChainPackage::Type::GHSArm) { if (type == McuToolChainPackage::ToolChainType::GHS || type == McuToolChainPackage::ToolChainType::GHSArm) {
// See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802 // See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802
// and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803 // and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM"); CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
@@ -389,13 +389,12 @@ void createAutomaticKits()
const auto createKits = [qtForMCUsPackage]() { const auto createKits = [qtForMCUsPackage]() {
if (McuSupportOptions::automaticKitCreationFromSettings()) { if (McuSupportOptions::automaticKitCreationFromSettings()) {
qtForMCUsPackage->updateStatus(); qtForMCUsPackage->updateStatus();
if (!qtForMCUsPackage->validStatus()) { if (!qtForMCUsPackage->isValidStatus()) {
switch (qtForMCUsPackage->status()) { switch (qtForMCUsPackage->status()) {
case McuAbstractPackage::Status::ValidPathInvalidPackage: { case McuAbstractPackage::Status::ValidPathInvalidPackage: {
const QString displayPath
= FilePath::fromString(qtForMCUsPackage->detectionPath()).toUserOutput();
printMessage(McuPackage::tr("Path %1 exists, but does not contain %2.") printMessage(McuPackage::tr("Path %1 exists, but does not contain %2.")
.arg(qtForMCUsPackage->path().toUserOutput(), displayPath), .arg(qtForMCUsPackage->path().toUserOutput(),
qtForMCUsPackage->detectionPath().toUserOutput()),
true); true);
break; break;
} }
@@ -408,7 +407,7 @@ void createAutomaticKits()
} }
case McuAbstractPackage::Status::EmptyPath: { case McuAbstractPackage::Status::EmptyPath: {
printMessage(McuPackage::tr("Missing %1. Add the path in Tools > Options > Devices > MCU.") printMessage(McuPackage::tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath()), .arg(qtForMCUsPackage->detectionPath().toUserOutput()),
true); true);
return; return;
} }
@@ -575,7 +574,7 @@ void fixExistingKits()
// Fix kit dependencies for known targets // Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
qtForMCUsPackage->updateStatus(); qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->validStatus()) { if (qtForMCUsPackage->isValidStatus()) {
FilePath dir = qtForMCUsPackage->path(); FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo; McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo); Sdk::targetsAndPackages(dir, &repo);

View File

@@ -28,26 +28,36 @@
#include "mcusupportversiondetection.h" #include "mcusupportversiondetection.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include <baremetal/baremetalconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <utils/infolabel.h> #include <utils/infolabel.h>
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <QDesktopServices> #include <QDesktopServices>
#include <QGridLayout> #include <QGridLayout>
#include <QToolButton> #include <QToolButton>
using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace McuSupport::Internal { namespace McuSupport::Internal {
McuPackage::McuPackage(const QString &label, McuPackage::McuPackage(const QString &label,
const FilePath &defaultPath, const FilePath &defaultPath,
const QString &detectionPath, const FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
const QString &envVarName, const QString &envVarName,
const QString &downloadUrl, const QString &downloadUrl,
const McuPackageVersionDetector *versionDetector) const McuPackageVersionDetector *versionDetector,
const bool addToSystemPath,
const FilePath &relativePathModifier)
: m_label(label) : m_label(label)
, m_defaultPath(Sdk::packagePathFromSettings(settingsKey, QSettings::SystemScope, defaultPath)) , m_defaultPath(Sdk::packagePathFromSettings(settingsKey, QSettings::SystemScope, defaultPath))
, m_detectionPath(detectionPath) , m_detectionPath(detectionPath)
@@ -55,10 +65,32 @@ McuPackage::McuPackage(const QString &label,
, m_versionDetector(versionDetector) , m_versionDetector(versionDetector)
, m_environmentVariableName(envVarName) , m_environmentVariableName(envVarName)
, m_downloadUrl(downloadUrl) , m_downloadUrl(downloadUrl)
, m_addToSystemPath(addToSystemPath)
, m_relativePathModifier(relativePathModifier)
{ {
m_path = Sdk::packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath); m_path = Sdk::packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath);
} }
QString McuPackage::label() const
{
return m_label;
}
const QString &McuPackage::environmentVariableName() const
{
return m_environmentVariableName;
}
bool McuPackage::isAddToSystemPath() const
{
return m_addToSystemPath;
}
void McuPackage::setVersions(const QStringList &versions)
{
m_versions = versions;
}
FilePath McuPackage::basePath() const FilePath McuPackage::basePath() const
{ {
return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path; return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path;
@@ -69,21 +101,131 @@ FilePath McuPackage::path() const
return basePath().resolvePath(m_relativePathModifier).absoluteFilePath(); return basePath().resolvePath(m_relativePathModifier).absoluteFilePath();
} }
QString McuPackage::label() const
{
return m_label;
}
FilePath McuPackage::defaultPath() const FilePath McuPackage::defaultPath() const
{ {
return m_defaultPath; return m_defaultPath;
} }
QString McuPackage::detectionPath() const FilePath McuPackage::detectionPath() const
{ {
return m_detectionPath; return m_detectionPath;
} }
void McuPackage::updatePath()
{
m_path = m_fileChooser->rawFilePath();
m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath);
updateStatus();
}
void McuPackage::updateStatus()
{
bool validPath = !m_path.isEmpty() && m_path.exists();
const FilePath detectionPath = basePath().resolvePath(m_detectionPath);
const bool validPackage = m_detectionPath.isEmpty() || detectionPath.exists();
m_detectedVersion = validPath && validPackage && m_versionDetector
? m_versionDetector->parseVersion(basePath().toString())
: QString();
const bool validVersion = m_detectedVersion.isEmpty() || m_versions.isEmpty()
|| m_versions.contains(m_detectedVersion);
m_status = validPath ? (validPackage ? (validVersion ? Status::ValidPackage
: Status::ValidPackageMismatchedVersion)
: Status::ValidPathInvalidPackage)
: m_path.isEmpty() ? Status::EmptyPath
: Status::InvalidPath;
emit statusChanged();
}
McuPackage::Status McuPackage::status() const
{
return m_status;
}
bool McuPackage::isValidStatus() const
{
return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion;
}
void McuPackage::updateStatusUi()
{
switch (m_status) {
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;
}
m_infoLabel->setText(statusText());
}
QString McuPackage::statusText() const
{
const QString displayPackagePath = m_path.toUserOutput();
const QString displayVersions = m_versions.join(" or ");
const QString outDetectionPath = m_detectionPath.toUserOutput();
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);
QString response;
switch (m_status) {
case Status::ValidPackage:
response = m_detectionPath.isEmpty()
? (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);
break;
case Status::ValidPackageMismatchedVersion: {
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);
response = tr("Path %1 is valid, %2 was found, %3.")
.arg(displayPackagePath, displayDetectedPath, versionWarning);
break;
}
case Status::ValidPathInvalidPackage:
response = tr("Path %1 exists, but does not contain %2.")
.arg(displayPackagePath, displayRequiredPath);
break;
case Status::InvalidPath:
response = tr("Path %1 does not exist.").arg(displayPackagePath);
break;
case Status::EmptyPath:
response = m_detectionPath.isEmpty()
? tr("Path is empty.")
: tr("Path is empty, %1 not found.").arg(displayRequiredPath);
break;
}
return response;
}
bool McuPackage::writeToSettings() const
{
const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey,
QSettings::UserScope,
m_defaultPath);
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey;
Core::ICore::settings()->setValueWithDefault(key, m_path.toString(), m_defaultPath.toString());
return savedPath != m_path;
}
QWidget *McuPackage::widget() QWidget *McuPackage::widget()
{ {
if (m_widget) if (m_widget)
@@ -127,164 +269,201 @@ QWidget *McuPackage::widget()
return m_widget; return m_widget;
} }
McuPackage::Status McuPackage::status() const
{
return m_status;
}
bool McuPackage::validStatus() const
{
return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion;
}
const QString &McuPackage::environmentVariableName() const
{
return m_environmentVariableName;
}
void McuPackage::setAddToPath(bool addToPath)
{
m_addToPath = addToPath;
}
bool McuPackage::addToPath() const
{
return m_addToPath;
}
bool McuPackage::writeToSettings() const
{
const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey,
QSettings::UserScope,
m_defaultPath);
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey;
Core::ICore::settings()->setValueWithDefault(key, m_path.toString(), m_defaultPath.toString());
return savedPath != m_path;
}
void McuPackage::setRelativePathModifier(const QString &path)
{
m_relativePathModifier = path;
}
void McuPackage::setVersions(const QStringList &versions)
{
m_versions = versions;
}
void McuPackage::updatePath()
{
m_path = m_fileChooser->rawFilePath();
m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath);
updateStatus();
}
void McuPackage::updateStatus()
{
bool validPath = !m_path.isEmpty() && m_path.exists();
const FilePath detectionPath = basePath() / m_detectionPath;
const bool validPackage = m_detectionPath.isEmpty() || detectionPath.exists();
m_detectedVersion = validPath && validPackage && m_versionDetector
? m_versionDetector->parseVersion(basePath().toString())
: QString();
const bool validVersion = m_detectedVersion.isEmpty() || m_versions.isEmpty()
|| m_versions.contains(m_detectedVersion);
m_status = validPath ? (validPackage ? (validVersion ? Status::ValidPackage
: Status::ValidPackageMismatchedVersion)
: Status::ValidPathInvalidPackage)
: m_path.isEmpty() ? Status::EmptyPath
: Status::InvalidPath;
emit statusChanged();
}
void McuPackage::updateStatusUi()
{
switch (m_status) {
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;
}
m_infoLabel->setText(statusText());
}
QString McuPackage::statusText() const
{
const QString displayPackagePath = m_path.toUserOutput();
const QString displayVersions = m_versions.join(" or ");
const QString outDetectionPath = FilePath::fromString(m_detectionPath).toUserOutput();
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);
QString response;
switch (m_status) {
case Status::ValidPackage:
response = m_detectionPath.isEmpty()
? (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);
break;
case Status::ValidPackageMismatchedVersion: {
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);
response = tr("Path %1 is valid, %2 was found, %3.")
.arg(displayPackagePath, displayDetectedPath, versionWarning);
break;
}
case Status::ValidPathInvalidPackage:
response = tr("Path %1 exists, but does not contain %2.")
.arg(displayPackagePath, displayRequiredPath);
break;
case Status::InvalidPath:
response = tr("Path %1 does not exist.").arg(displayPackagePath);
break;
case Status::EmptyPath:
response = m_detectionPath.isEmpty()
? tr("Path is empty.")
: tr("Path is empty, %1 not found.").arg(displayRequiredPath);
break;
}
return response;
}
McuToolChainPackage::McuToolChainPackage(const QString &label, McuToolChainPackage::McuToolChainPackage(const QString &label,
const FilePath &defaultPath, const FilePath &defaultPath,
const QString &detectionPath, const FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
McuToolChainPackage::Type type, McuToolChainPackage::ToolChainType type,
const QString &envVarName, const QString &envVarName,
const McuPackageVersionDetector *versionDetector) const McuPackageVersionDetector *versionDetector)
: McuPackage(label, defaultPath, detectionPath, settingsKey, envVarName, {}, versionDetector) : McuPackage(label, defaultPath, detectionPath, settingsKey, envVarName, {}, versionDetector)
, m_type(type) , m_type(type)
{} {}
McuToolChainPackage::Type McuToolChainPackage::type() const McuToolChainPackage::ToolChainType McuToolChainPackage::toolchainType() const
{ {
return m_type; return m_type;
} }
bool McuToolChainPackage::isDesktopToolchain() const bool McuToolChainPackage::isDesktopToolchain() const
{ {
return m_type == Type::MSVC || m_type == Type::GCC; return m_type == ToolChainType::MSVC || m_type == ToolChainType::GCC;
}
static ToolChain *msvcToolChain(Id language)
{
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;
}
static ToolChain *gccToolChain(Id language)
{
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) {
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
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: {
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
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"
: "/bar/foo-keil-%1")
.arg(compilerName);
const FilePath compiler = path().pathAppended(comp).withExecutableSuffix();
return armGccToolChain(compiler, language);
}
default:
Q_UNREACHABLE();
}
}
QString McuToolChainPackage::toolChainName() const
{
switch (m_type) {
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");
}
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
}
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();
}
const FilePath command = path().pathAppended(sub).withExecutableSuffix();
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);
} }

View File

@@ -55,33 +55,35 @@ class McuPackage : public McuAbstractPackage
public: public:
McuPackage(const QString &label, McuPackage(const QString &label,
const Utils::FilePath &defaultPath, const Utils::FilePath &defaultPath,
const QString &detectionPath, const Utils::FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
const QString &envVarName = {}, const QString &envVarName = {},
const QString &downloadUrl = {}, const QString &downloadUrl = {},
const McuPackageVersionDetector *versionDetector = nullptr); const McuPackageVersionDetector *versionDetector = nullptr,
const bool addToPath = false,
const Utils::FilePath &relativePathModifier = Utils::FilePath());
~McuPackage() override = default; ~McuPackage() override = default;
QString label() const override;
const QString &environmentVariableName() const override;
bool isAddToSystemPath() const override;
void setVersions(const QStringList &versions) override;
Utils::FilePath basePath() const override; Utils::FilePath basePath() const override;
Utils::FilePath path() const override; Utils::FilePath path() const override;
QString label() const override;
Utils::FilePath defaultPath() const override; Utils::FilePath defaultPath() const override;
QString detectionPath() const override; Utils::FilePath detectionPath() const override;
QString statusText() const override;
void updateStatus() override;
void updateStatus() override;
Status status() const override; Status status() const override;
bool validStatus() const override; bool isValidStatus() const override;
void setAddToPath(bool addToPath) override; QString statusText() const override;
bool addToPath() const override;
bool writeToSettings() const override; bool writeToSettings() const override;
void setRelativePathModifier(const QString &path) override;
void setVersions(const QStringList &versions) override;
QWidget *widget() override; QWidget *widget() override;
const QString &environmentVariableName() const override;
private: private:
void updatePath(); void updatePath();
void updateStatusUi(); void updateStatusUi();
@@ -92,17 +94,17 @@ private:
const QString m_label; const QString m_label;
const Utils::FilePath m_defaultPath; const Utils::FilePath m_defaultPath;
const QString m_detectionPath; const Utils::FilePath m_detectionPath;
const QString m_settingsKey; const QString m_settingsKey;
const McuPackageVersionDetector *m_versionDetector; const McuPackageVersionDetector *m_versionDetector;
Utils::FilePath m_path; Utils::FilePath m_path;
QString m_relativePathModifier; // relative path to m_path to be returned by path() Utils::FilePath m_relativePathModifier; // relative path to m_path to be returned by path()
QString m_detectedVersion; QString m_detectedVersion;
QStringList m_versions; QStringList m_versions;
const QString m_environmentVariableName; const QString m_environmentVariableName;
const QString m_downloadUrl; const QString m_downloadUrl;
bool m_addToPath = false; const bool m_addToSystemPath;
Status m_status = Status::InvalidPath; Status m_status = Status::InvalidPath;
}; };
@@ -110,17 +112,17 @@ private:
class McuToolChainPackage : public McuPackage class McuToolChainPackage : public McuPackage
{ {
public: public:
enum class Type { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported }; enum class ToolChainType { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported };
McuToolChainPackage(const QString &label, McuToolChainPackage(const QString &label,
const Utils::FilePath &defaultPath, const Utils::FilePath &defaultPath,
const QString &detectionPath, const Utils::FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
Type type, ToolChainType toolchainType,
const QString &envVarName = {}, const QString &envVarName = {},
const McuPackageVersionDetector *versionDetector = nullptr); const McuPackageVersionDetector *versionDetector = nullptr);
Type type() const; ToolChainType toolchainType() const;
bool isDesktopToolchain() const; bool isDesktopToolchain() const;
ProjectExplorer::ToolChain *toolChain(Utils::Id language) const; ProjectExplorer::ToolChain *toolChain(Utils::Id language) const;
QString toolChainName() const; QString toolChainName() const;
@@ -128,7 +130,7 @@ public:
QVariant debuggerId() const; QVariant debuggerId() const;
private: private:
const Type m_type; const ToolChainType m_type;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -134,7 +134,7 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
{ {
deletePackagesAndTargets(); deletePackagesAndTargets();
qtForMCUsSdkPackage->updateStatus(); qtForMCUsSdkPackage->updateStatus();
if (qtForMCUsSdkPackage->validStatus()) if (qtForMCUsSdkPackage->isValidStatus())
Sdk::targetsAndPackages(dir, &sdkRepository); Sdk::targetsAndPackages(dir, &sdkRepository);
for (const auto &package : qAsConst(sdkRepository.packages)) for (const auto &package : qAsConst(sdkRepository.packages))
connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::packagesChanged); connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::packagesChanged);
@@ -165,19 +165,19 @@ void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &en
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{ {
switch (tcPackage->type()) { switch (tcPackage->toolchainType()) {
case McuToolChainPackage::Type::Unsupported: case McuToolChainPackage::ToolChainType::Unsupported:
return; return;
case McuToolChainPackage::Type::GHS: case McuToolChainPackage::ToolChainType::GHS:
case McuToolChainPackage::Type::GHSArm: case McuToolChainPackage::ToolChainType::GHSArm:
return; // No Green Hills toolchain, because support for it is missing. return; // No Green Hills toolchain, because support for it is missing.
case McuToolChainPackage::Type::IAR: case McuToolChainPackage::ToolChainType::IAR:
case McuToolChainPackage::Type::KEIL: case McuToolChainPackage::ToolChainType::KEIL:
case McuToolChainPackage::Type::MSVC: case McuToolChainPackage::ToolChainType::MSVC:
case McuToolChainPackage::Type::GCC: case McuToolChainPackage::ToolChainType::GCC:
case McuToolChainPackage::Type::ArmGcc: case McuToolChainPackage::ToolChainType::ArmGcc:
ToolChainKitAspect::setToolChain(k, ToolChainKitAspect::setToolChain(k,
tcPackage->toolChain( tcPackage->toolChain(
ProjectExplorer::Constants::C_LANGUAGE_ID)); ProjectExplorer::Constants::C_LANGUAGE_ID));
@@ -198,17 +198,17 @@ static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
return; return;
} }
switch (tcPackage->type()) { switch (tcPackage->toolchainType()) {
case McuToolChainPackage::Type::Unsupported: case McuToolChainPackage::ToolChainType::Unsupported:
case McuToolChainPackage::Type::GHS: case McuToolChainPackage::ToolChainType::GHS:
case McuToolChainPackage::Type::GHSArm: case McuToolChainPackage::ToolChainType::GHSArm:
case McuToolChainPackage::Type::IAR: case McuToolChainPackage::ToolChainType::IAR:
return; // No Green Hills and IAR debugger, because support for it is missing. return; // No Green Hills and IAR debugger, because support for it is missing.
case McuToolChainPackage::Type::KEIL: case McuToolChainPackage::ToolChainType::KEIL:
case McuToolChainPackage::Type::MSVC: case McuToolChainPackage::ToolChainType::MSVC:
case McuToolChainPackage::Type::GCC: case McuToolChainPackage::ToolChainType::GCC:
case McuToolChainPackage::Type::ArmGcc: { case McuToolChainPackage::ToolChainType::ArmGcc: {
const QVariant debuggerId = tcPackage->debuggerId(); const QVariant debuggerId = tcPackage->debuggerId();
if (debuggerId.isValid()) { if (debuggerId.isValid()) {
Debugger::DebuggerKitAspect::setDebugger(k, debuggerId); Debugger::DebuggerKitAspect::setDebugger(k, debuggerId);
@@ -250,7 +250,7 @@ void McuSupportOptions::setKitEnvironment(Kit *k,
pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput()); pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput());
auto processPackage = [&pathAdditions, &changes](const McuAbstractPackage *package) { auto processPackage = [&pathAdditions, &changes](const McuAbstractPackage *package) {
if (package->addToPath()) if (package->isAddToSystemPath())
pathAdditions.append(package->path().toUserOutput()); pathAdditions.append(package->path().toUserOutput());
if (!package->environmentVariableName().isEmpty()) if (!package->environmentVariableName().isEmpty())
changes.append({package->environmentVariableName(), package->path().toUserOutput()}); changes.append({package->environmentVariableName(), package->path().toUserOutput()});
@@ -279,7 +279,7 @@ static void setKitDependencies(Kit *k,
auto processPackage = [&dependencies](const McuAbstractPackage *package) { auto processPackage = [&dependencies](const McuAbstractPackage *package) {
if (!package->environmentVariableName().isEmpty()) if (!package->environmentVariableName().isEmpty())
dependencies.append({package->environmentVariableName(), dependencies.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->detectionPath())}); package->detectionPath().toUserOutput()});
}; };
for (auto package : mcuTarget->packages()) for (auto package : mcuTarget->packages())
processPackage(package); processPackage(package);
@@ -297,7 +297,7 @@ void McuSupportOptions::updateKitEnvironment(Kit *k, const McuTarget *mcuTarget)
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k); EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k);
for (auto package : mcuTarget->packages()) { for (auto package : mcuTarget->packages()) {
const QString varName = package->environmentVariableName(); const QString varName = package->environmentVariableName();
if (!varName.isEmpty() && package->validStatus()) { if (!varName.isEmpty() && package->isValidStatus()) {
const int index = Utils::indexOf(changes, [varName](const EnvironmentItem &item) { const int index = Utils::indexOf(changes, [varName](const EnvironmentItem &item) {
return item.name == varName; return item.name == varName;
}); });
@@ -324,8 +324,8 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k); CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously // CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
if (mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHS if (mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHS
&& mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHSArm) { && mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHSArm) {
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}")); config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}")); config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
} }
@@ -363,8 +363,8 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
CMakeConfigurationKitAspect::setConfiguration(k, config); CMakeConfigurationKitAspect::setConfiguration(k, config);
if (HostOsInfo::isWindowsHost()) { if (HostOsInfo::isWindowsHost()) {
auto type = mcuTarget->toolChainPackage()->type(); auto type = mcuTarget->toolChainPackage()->toolchainType();
if (type == McuToolChainPackage::Type::GHS || type == McuToolChainPackage::Type::GHSArm) { if (type == McuToolChainPackage::ToolChainType::GHS || type == McuToolChainPackage::ToolChainType::GHSArm) {
// See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802 // See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802
// and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803 // and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM"); CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
@@ -418,7 +418,7 @@ void McuSupportOptions::deletePackagesAndTargets()
void McuSupportOptions::checkUpgradeableKits() void McuSupportOptions::checkUpgradeableKits()
{ {
if (!qtForMCUsSdkPackage->validStatus() || sdkRepository.mcuTargets.length() == 0) if (!qtForMCUsSdkPackage->isValidStatus() || sdkRepository.mcuTargets.length() == 0)
return; return;
if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) { if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) {

View File

@@ -196,7 +196,7 @@ void McuSupportOptionsWidget::updateStatus()
// Page elements // Page elements
{ {
m_qtForMCUsSdkGroupBox->setVisible(cMakeAvailable); m_qtForMCUsSdkGroupBox->setVisible(cMakeAvailable);
const bool valid = cMakeAvailable && m_options.qtForMCUsSdkPackage->validStatus(); const bool valid = cMakeAvailable && m_options.qtForMCUsSdkPackage->isValidStatus();
const bool ready = valid && mcuTarget; const bool ready = valid && mcuTarget;
m_mcuTargetsGroupBox->setVisible(ready); m_mcuTargetsGroupBox->setVisible(ready);
m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty()); m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty());

View File

@@ -71,24 +71,24 @@ McuPackage *createQtForMCUsPackage()
{ {
return new McuPackage(McuPackage::tr("Qt for MCUs SDK"), return new McuPackage(McuPackage::tr("Qt for MCUs SDK"),
FileUtils::homePath(), // defaultPath FileUtils::homePath(), // defaultPath
FilePath("bin/qmltocpp").withExecutableSuffix().toString(), // detectionPath FilePath("bin/qmltocpp").withExecutableSuffix(), // detectionPath
Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK, // settingsKey Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK, // settingsKey
QStringLiteral("Qul_DIR")); // envVarName QStringLiteral("Qul_DIR")); // envVarName
} }
static McuToolChainPackage *createMsvcToolChainPackage() static McuToolChainPackage *createMsvcToolChainPackage()
{ {
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::Type::MSVC); return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::ToolChainType::MSVC);
} }
static McuToolChainPackage *createGccToolChainPackage() static McuToolChainPackage *createGccToolChainPackage()
{ {
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::Type::GCC); return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::ToolChainType::GCC);
} }
static McuToolChainPackage *createUnsupportedToolChainPackage() static McuToolChainPackage *createUnsupportedToolChainPackage()
{ {
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::Type::Unsupported); return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::ToolChainType::Unsupported);
} }
static McuToolChainPackage *createArmGccPackage() static McuToolChainPackage *createArmGccPackage()
@@ -109,7 +109,7 @@ static McuToolChainPackage *createArmGccPackage()
} }
} }
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"); const Utils::FilePath detectionPath = FilePath("bin/arm-none-eabi-g++").withExecutableSuffix();
const auto versionDetector const auto versionDetector
= new McuPackageExecutableVersionDetector(detectionPath, = new McuPackageExecutableVersionDetector(detectionPath,
{"--version"}, {"--version"},
@@ -119,7 +119,7 @@ static McuToolChainPackage *createArmGccPackage()
defaultPath, defaultPath,
detectionPath, detectionPath,
"GNUArmEmbeddedToolchain", // settingsKey "GNUArmEmbeddedToolchain", // settingsKey
McuToolChainPackage::Type::ArmGcc, McuToolChainPackage::ToolChainType::ArmGcc,
envVar, envVar,
versionDetector); versionDetector);
} }
@@ -131,16 +131,15 @@ static McuToolChainPackage *createGhsToolchainPackage()
const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
const auto versionDetector const auto versionDetector
= new McuPackageExecutableVersionDetector(Utils::HostOsInfo::withExecutableSuffix("as850"), = new McuPackageExecutableVersionDetector(FilePath("as850").withExecutableSuffix(),
{"-V"}, {"-V"},
"\\bv(\\d+\\.\\d+\\.\\d+)\\b"); "\\bv(\\d+\\.\\d+\\.\\d+)\\b");
return new McuToolChainPackage("Green Hills Compiler", return new McuToolChainPackage("Green Hills Compiler",
defaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix( FilePath("ccv850").withExecutableSuffix(), // detectionPath
"ccv850"), // detectionPath
"GHSToolchain", // settingsKey "GHSToolchain", // settingsKey
McuToolChainPackage::Type::GHS, McuToolChainPackage::ToolChainType::GHS,
envVar, envVar,
versionDetector); versionDetector);
} }
@@ -152,15 +151,15 @@ static McuToolChainPackage *createGhsArmToolchainPackage()
const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
const auto versionDetector const auto versionDetector
= new McuPackageExecutableVersionDetector(Utils::HostOsInfo::withExecutableSuffix("asarm"), = new McuPackageExecutableVersionDetector(FilePath("asarm").withExecutableSuffix(),
{"-V"}, {"-V"},
"\\bv(\\d+\\.\\d+\\.\\d+)\\b"); "\\bv(\\d+\\.\\d+\\.\\d+)\\b");
return new McuToolChainPackage("Green Hills Compiler for ARM", return new McuToolChainPackage("Green Hills Compiler for ARM",
defaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix("cxarm"), // detectionPath FilePath("cxarm").withExecutableSuffix(), // detectionPath
"GHSArmToolchain", // settingsKey "GHSArmToolchain", // settingsKey
McuToolChainPackage::Type::GHSArm, McuToolChainPackage::ToolChainType::GHSArm,
envVar, envVar,
versionDetector); versionDetector);
} }
@@ -183,7 +182,7 @@ static McuToolChainPackage *createIarToolChainPackage()
} }
} }
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm"); const FilePath detectionPath = FilePath("bin/iccarm").withExecutableSuffix();
const auto versionDetector const auto versionDetector
= new McuPackageExecutableVersionDetector(detectionPath, = new McuPackageExecutableVersionDetector(detectionPath,
{"--version"}, {"--version"},
@@ -193,7 +192,7 @@ static McuToolChainPackage *createIarToolChainPackage()
defaultPath, defaultPath,
detectionPath, detectionPath,
"IARToolchain", // settings key "IARToolchain", // settings key
McuToolChainPackage::Type::IAR, McuToolChainPackage::ToolChainType::IAR,
envVar, envVar,
versionDetector); versionDetector);
} }
@@ -237,17 +236,24 @@ static McuPackage *createStm32CubeProgrammerPackage()
if (programPath.exists()) if (programPath.exists())
defaultPath = programPath; defaultPath = programPath;
} }
const FilePath detectionPath = FilePath::fromString(
QLatin1String(Utils::HostOsInfo::isWindowsHost()
? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh")
);
auto result auto result
= new McuPackage(McuPackage::tr("STM32CubeProgrammer"), = new McuPackage(McuPackage::tr("STM32CubeProgrammer"),
defaultPath, defaultPath,
QLatin1String(Utils::HostOsInfo::isWindowsHost() detectionPath,
? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh"), // detection path
"Stm32CubeProgrammer", "Stm32CubeProgrammer",
{}, // env var {}, // env var
"https://www.st.com/en/development-tools/stm32cubeprog.html"); // download url "https://www.st.com/en/development-tools/stm32cubeprog.html", // download url
result->setRelativePathModifier("/bin"); nullptr, // version detector
result->setAddToPath(true); true, // add to path
"/bin" // relative path modifier
);
return result; return result;
} }
@@ -276,8 +282,7 @@ static McuPackage *createMcuXpressoIdePackage()
return new McuPackage("MCUXpresso IDE", return new McuPackage("MCUXpresso IDE",
defaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix( FilePath("ide/binaries/crt_emu_cm_redlink").withExecutableSuffix(), // detection path
"ide/binaries/crt_emu_cm_redlink"), // detection path
"MCUXpressoIDE", // settings key "MCUXpressoIDE", // settings key
envVar, envVar,
"https://www.nxp.com/mcuxpresso/ide"); // download url "https://www.nxp.com/mcuxpresso/ide"); // download url
@@ -303,7 +308,7 @@ static McuPackage *createCypressProgrammerPackage()
auto result = new McuPackage("Cypress Auto Flash Utility", auto result = new McuPackage("Cypress Auto Flash Utility",
defaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix("/bin/openocd"), FilePath("/bin/openocd").withExecutableSuffix(),
"CypressAutoFlashUtil", "CypressAutoFlashUtil",
envVar); envVar);
return result; return result;
@@ -329,7 +334,7 @@ static McuPackage *createRenesasProgrammerPackage()
auto result = new McuPackage("Renesas Flash Programmer", auto result = new McuPackage("Renesas Flash Programmer",
defaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix("rfp-cli"), FilePath("rfp-cli").withExecutableSuffix(),
"RenesasFlashProgrammer", "RenesasFlashProgrammer",
envVar); envVar);
return result; return result;
@@ -538,7 +543,7 @@ protected:
QVector<McuAbstractPackage *> required3rdPartyPkgs; QVector<McuAbstractPackage *> required3rdPartyPkgs;
// Desktop toolchains don't need any additional settings // Desktop toolchains don't need any additional settings
if (tcPkg && !tcPkg->isDesktopToolchain() if (tcPkg && !tcPkg->isDesktopToolchain()
&& tcPkg->type() != McuToolChainPackage::Type::Unsupported) && tcPkg->toolchainType() != McuToolChainPackage::ToolChainType::Unsupported)
required3rdPartyPkgs.append(tcPkg); required3rdPartyPkgs.append(tcPkg);
// Add setting specific to platform IDE // Add setting specific to platform IDE

View File

@@ -46,7 +46,7 @@ QString matchRegExp(const QString &text, const QString &regExp)
McuPackageVersionDetector::McuPackageVersionDetector() {} McuPackageVersionDetector::McuPackageVersionDetector() {}
McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector( McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector(
const QString &detectionPath, const QStringList &detectionArgs, const QString &detectionRegExp) const Utils::FilePath &detectionPath, const QStringList &detectionArgs, const QString &detectionRegExp)
: McuPackageVersionDetector() : McuPackageVersionDetector()
, m_detectionPath(detectionPath) , m_detectionPath(detectionPath)
, m_detectionArgs(detectionArgs) , m_detectionArgs(detectionArgs)
@@ -58,7 +58,7 @@ QString McuPackageExecutableVersionDetector::parseVersion(const QString &package
if (m_detectionPath.isEmpty() || m_detectionRegExp.isEmpty()) if (m_detectionPath.isEmpty() || m_detectionRegExp.isEmpty())
return QString(); return QString();
const Utils::FilePath binaryPath = Utils::FilePath::fromString(packagePath) / m_detectionPath; const Utils::FilePath binaryPath = Utils::FilePath::fromString(packagePath).resolvePath(m_detectionPath);
if (!binaryPath.exists()) if (!binaryPath.exists())
return QString(); return QString();

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include <QObject> #include <QObject>
#include <utils/filepath.h>
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
@@ -43,13 +44,13 @@ public:
class McuPackageExecutableVersionDetector : public McuPackageVersionDetector class McuPackageExecutableVersionDetector : public McuPackageVersionDetector
{ {
public: public:
McuPackageExecutableVersionDetector(const QString &detectionPath, McuPackageExecutableVersionDetector(const Utils::FilePath &detectionPath,
const QStringList &detectionArgs, const QStringList &detectionArgs,
const QString &detectionRegExp); const QString &detectionRegExp);
QString parseVersion(const QString &packagePath) const final; QString parseVersion(const QString &packagePath) const final;
private: private:
const QString m_detectionPath; const Utils::FilePath m_detectionPath;
const QStringList m_detectionArgs; const QStringList m_detectionArgs;
const QString m_detectionRegExp; const QString m_detectionRegExp;
}; };

View File

@@ -26,196 +26,14 @@
#include "mcutarget.h" #include "mcutarget.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcukitmanager.h" #include "mcukitmanager.h"
#include "mcusupportplugin.h" #include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h> #include <utils/algorithm.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace McuSupport::Internal { namespace McuSupport::Internal {
static ToolChain *msvcToolChain(Id language)
{
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;
}
static ToolChain *gccToolChain(Id language)
{
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) {
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
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 Type::MSVC:
return msvcToolChain(language);
case Type::GCC:
return gccToolChain(language);
case Type::IAR: {
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
return iarToolChain(compiler, language);
}
case Type::ArmGcc:
case Type::KEIL:
case Type::GHS:
case Type::GHSArm:
case Type::Unsupported: {
const QLatin1String compilerName(
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
const QString comp = QLatin1String(m_type == Type::ArmGcc ? "/bin/arm-none-eabi-%1"
: "/bar/foo-keil-%1")
.arg(compilerName);
const FilePath compiler = path().pathAppended(comp).withExecutableSuffix();
return armGccToolChain(compiler, language);
}
default:
Q_UNREACHABLE();
}
}
QString McuToolChainPackage::toolChainName() const
{
switch (m_type) {
case Type::ArmGcc:
return QLatin1String("armgcc");
case Type::IAR:
return QLatin1String("iar");
case Type::KEIL:
return QLatin1String("keil");
case Type::GHS:
return QLatin1String("ghs");
case Type::GHSArm:
return QLatin1String("ghs-arm");
default:
return QLatin1String("unsupported");
}
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
}
QVariant McuToolChainPackage::debuggerId() const
{
using namespace Debugger;
QString sub, displayName;
DebuggerEngineType engineType;
switch (m_type) {
case Type::ArmGcc: {
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
displayName = McuPackage::tr("Arm GDB at %1");
engineType = Debugger::GdbEngineType;
break;
}
case Type::IAR: {
sub = QString::fromLatin1("../common/bin/CSpyBat");
displayName = QLatin1String("CSpy");
engineType = Debugger::NoEngineType; // support for IAR missing
break;
}
case Type::KEIL: {
sub = QString::fromLatin1("UV4/UV4");
displayName = QLatin1String("KEIL uVision Debugger");
engineType = Debugger::UvscEngineType;
break;
}
default:
return QVariant();
}
const FilePath command = path().pathAppended(sub).withExecutableSuffix();
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);
}
McuTarget::McuTarget(const QVersionNumber &qulVersion, McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform, const Platform &platform,
OS os, OS os,
@@ -254,7 +72,7 @@ bool McuTarget::isValid() const
{ {
return Utils::allOf(packages(), [](McuAbstractPackage *package) { return Utils::allOf(packages(), [](McuAbstractPackage *package) {
package->updateStatus(); package->updateStatus();
return package->validStatus(); return package->isValidStatus();
}); });
} }
@@ -262,7 +80,7 @@ void McuTarget::printPackageProblems() const
{ {
for (auto package : packages()) { for (auto package : packages()) {
package->updateStatus(); package->updateStatus();
if (!package->validStatus()) if (!package->isValidStatus())
printMessage(tr("Error creating kit for target %1, package %2: %3") printMessage(tr("Error creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this), .arg(McuKitManager::kitName(this),
package->label(), package->label(),

View File

@@ -39,17 +39,15 @@ public:
MOCK_METHOD(Utils::FilePath, path, (), (const)); MOCK_METHOD(Utils::FilePath, path, (), (const));
MOCK_METHOD(QString, label, (), (const)); MOCK_METHOD(QString, label, (), (const));
MOCK_METHOD(Utils::FilePath, defaultPath, (), (const)); MOCK_METHOD(Utils::FilePath, defaultPath, (), (const));
MOCK_METHOD(QString, detectionPath, (), (const)); MOCK_METHOD(Utils::FilePath, detectionPath, (), (const));
MOCK_METHOD(QString, statusText, (), (const)); MOCK_METHOD(QString, statusText, (), (const));
MOCK_METHOD(void, updateStatus, ()); MOCK_METHOD(void, updateStatus, ());
MOCK_METHOD(Status, status, (), (const)); MOCK_METHOD(Status, status, (), (const));
MOCK_METHOD(bool, validStatus, (), (const)); MOCK_METHOD(bool, isValidStatus, (), (const));
MOCK_METHOD(const QString &, environmentVariableName, (), (const)); MOCK_METHOD(const QString &, environmentVariableName, (), (const));
MOCK_METHOD(void, setAddToPath, (bool) ); MOCK_METHOD(bool, isAddToSystemPath, (), (const));
MOCK_METHOD(bool, addToPath, (), (const));
MOCK_METHOD(bool, writeToSettings, (), (const)); MOCK_METHOD(bool, writeToSettings, (), (const));
MOCK_METHOD(void, setRelativePathModifier, (const QString &) );
MOCK_METHOD(void, setVersions, (const QStringList &) ); MOCK_METHOD(void, setVersions, (const QStringList &) );
MOCK_METHOD(QWidget *, widget, ()); MOCK_METHOD(QWidget *, widget, ());

View File

@@ -47,7 +47,7 @@ using Utils::FilePath;
void McuSupportTest::initTestCase() void McuSupportTest::initTestCase()
{ {
EXPECT_CALL(freeRtosPackage, environmentVariableName()).WillRepeatedly(ReturnRef(freeRtosEnvVar)); EXPECT_CALL(freeRtosPackage, environmentVariableName()).WillRepeatedly(ReturnRef(freeRtosEnvVar));
EXPECT_CALL(freeRtosPackage, validStatus()).WillRepeatedly(Return(true)); EXPECT_CALL(freeRtosPackage, isValidStatus()).WillRepeatedly(Return(true));
EXPECT_CALL(freeRtosPackage, path()) EXPECT_CALL(freeRtosPackage, path())
.WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath))); .WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath)));
} }