McuSupport: Add support for kits with IAR compiler defined

- added IAR toolchain factory similar to ARM GCC one
- extended kitName with used compiler name
- added Unsupported toolchain type to fix crash after creating kit with not
  recognized toolchainID

Fixes: QTCREATORBUG-24898
Change-Id: I28b8376ca4bc88d3d75e17bd242ac49f0ee09845
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: <christiaan.janssen@qt.io>
This commit is contained in:
Dawid Sliwa
2020-11-13 14:00:18 +01:00
committed by Dawid Śliwa
parent c9f5ce51e0
commit 3929917ecb
6 changed files with 109 additions and 14 deletions

View File

@@ -1,6 +1,6 @@
add_qtc_plugin(McuSupport add_qtc_plugin(McuSupport
DEPENDS Qt5::Core DEPENDS Qt5::Core
PLUGIN_DEPENDS Core ProjectExplorer Debugger CMakeProjectManager QtSupport PLUGIN_DEPENDS Core Baremetal ProjectExplorer Debugger CMakeProjectManager QtSupport
SOURCES SOURCES
mcusupport.qrc mcusupport.qrc
mcusupport_global.h mcusupport_global.h

View File

@@ -8,6 +8,7 @@ QtcPlugin {
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "Core" } Depends { name: "Core" }
Depends { name: "Baremetal" }
Depends { name: "ProjectExplorer" } Depends { name: "ProjectExplorer" }
Depends { name: "Debugger" } Depends { name: "Debugger" }
Depends { name: "CMakeProjectManager" } Depends { name: "CMakeProjectManager" }

View File

@@ -6,6 +6,7 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \ QTC_PLUGIN_DEPENDS += \
coreplugin \ coreplugin \
baremetal \
projectexplorer \ projectexplorer \
debugger \ debugger \
cmakeprojectmanager \ cmakeprojectmanager \

View File

@@ -27,6 +27,7 @@
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include <baremetal/baremetalconstants.h>
#include <cmakeprojectmanager/cmaketoolmanager.h> #include <cmakeprojectmanager/cmaketoolmanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/helpmanager.h> #include <coreplugin/helpmanager.h>
@@ -330,6 +331,33 @@ static ToolChain *armGccToolChain(const FilePath &path, Id language)
return toolChain; return toolChain;
} }
static ToolChain *iarToolChain(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) {
const QList<ToolChain*> detected = iarFactory->autoDetect(QList<ToolChain*>());
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 ToolChain *McuToolChainPackage::toolChain(Id language) const
{ {
ToolChain *tc = nullptr; ToolChain *tc = nullptr;
@@ -337,6 +365,9 @@ ToolChain *McuToolChainPackage::toolChain(Id language) const
tc = msvcToolChain(language); tc = msvcToolChain(language);
else if (m_type == TypeGCC) else if (m_type == TypeGCC)
tc = gccToolChain(language); tc = gccToolChain(language);
else if (m_type == TypeIAR) {
tc = iarToolChain(language);
}
else { else {
const QLatin1String compilerName( const QLatin1String compilerName(
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++"); language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
@@ -344,20 +375,25 @@ ToolChain *McuToolChainPackage::toolChain(Id language) const
HostOsInfo::withExecutableSuffix( HostOsInfo::withExecutableSuffix(
path() + ( path() + (
m_type == TypeArmGcc m_type == TypeArmGcc
? "/bin/arm-none-eabi-%1" : m_type == TypeIAR ? "/bin/arm-none-eabi-%1" : "/bar/foo-keil-%1")).arg(compilerName));
? "/foo/bar-iar-%1" : "/bar/foo-keil-%1")).arg(compilerName));
tc = armGccToolChain(compiler, language); tc = armGccToolChain(compiler, language);
} }
return tc; return tc;
} }
QString McuToolChainPackage::cmakeToolChainFileName() const QString McuToolChainPackage::toolChainName() const
{ {
return QLatin1String(m_type == TypeArmGcc return QLatin1String(m_type == TypeArmGcc
? "armgcc" : m_type == McuToolChainPackage::TypeIAR ? "armgcc" : m_type == McuToolChainPackage::TypeIAR
? "iar" : m_type == McuToolChainPackage::TypeKEIL ? "iar" : m_type == McuToolChainPackage::TypeKEIL
? "keil" : "ghs") + QLatin1String(".cmake"); ? "keil" : m_type == McuToolChainPackage::TypeGHS
? "ghs" : "unsupported");
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
} }
QVariant McuToolChainPackage::debuggerId() const QVariant McuToolChainPackage::debuggerId() const
@@ -368,7 +404,7 @@ QVariant McuToolChainPackage::debuggerId() const
HostOsInfo::withExecutableSuffix(path() + ( HostOsInfo::withExecutableSuffix(path() + (
m_type == TypeArmGcc m_type == TypeArmGcc
? "/bin/arm-none-eabi-gdb-py" : m_type == TypeIAR ? "/bin/arm-none-eabi-gdb-py" : m_type == TypeIAR
? "/foo/bar-iar-gdb" : "/bar/foo-keil-gdb"))); ? "../common/bin/CSpyBat" : "/bar/foo-keil-gdb")));
const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command); const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command);
QVariant debuggerId; QVariant debuggerId;
if (!debugger) { if (!debugger) {
@@ -376,7 +412,7 @@ QVariant McuToolChainPackage::debuggerId() const
newDebugger.setCommand(command); newDebugger.setCommand(command);
const QString displayName = m_type == TypeArmGcc const QString displayName = m_type == TypeArmGcc
? McuPackage::tr("Arm GDB at %1") ? McuPackage::tr("Arm GDB at %1")
: m_type == TypeIAR ? QLatin1String("/foo/bar-iar-gdb") : m_type == TypeIAR ? QLatin1String("CSpy")
: QLatin1String("/bar/foo-keil-gdb"); : QLatin1String("/bar/foo-keil-gdb");
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput())); newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
debuggerId = DebuggerItemManager::registerDebugger(newDebugger); debuggerId = DebuggerItemManager::registerDebugger(newDebugger);
@@ -561,7 +597,8 @@ static void setKitProperties(const QString &kitName, Kit *k, const McuTarget *mc
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{ {
// No Green Hills toolchain, because support for it is missing. // No Green Hills toolchain, because support for it is missing.
if (tcPackage->type() == McuToolChainPackage::TypeGHS) if (tcPackage->type() == McuToolChainPackage::TypeUnsupported
|| tcPackage->type() == McuToolChainPackage::TypeGHS)
return; return;
ToolChainKitAspect::setToolChain(k, tcPackage->toolChain( ToolChainKitAspect::setToolChain(k, tcPackage->toolChain(
@@ -575,8 +612,10 @@ static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
// Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain // Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain
// We rely on that at least in the Desktop case. // We rely on that at least in the Desktop case.
if (tcPackage->isDesktopToolchain() if (tcPackage->isDesktopToolchain()
// No Green Hills debugger, because support for it is missing. // No Green Hills and IAR debugger, because support for it is missing.
|| tcPackage->type() == McuToolChainPackage::TypeGHS) || tcPackage->type() == McuToolChainPackage::TypeUnsupported
|| tcPackage->type() == McuToolChainPackage::TypeGHS
|| tcPackage->type() == McuToolChainPackage::TypeIAR)
return; return;
Debugger::DebuggerKitAspect::setDebugger(k, tcPackage->debuggerId()); Debugger::DebuggerKitAspect::setDebugger(k, tcPackage->debuggerId());
@@ -676,18 +715,23 @@ QString McuSupportOptions::kitName(const McuTarget *mcuTarget)
// Starting from Qul 1.4 each OS is a separate platform // Starting from Qul 1.4 each OS is a separate platform
os = QLatin1String(" FreeRTOS"); os = QLatin1String(" FreeRTOS");
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
? QString::fromLatin1(" (%1)").arg(tcPkg->toolChainName().toUpper())
: "";
const QString colorDepth = mcuTarget->colorDepth() > 0 const QString colorDepth = mcuTarget->colorDepth() > 0
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth()) ? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
: ""; : "";
const QString targetName = mcuTarget->platform().displayName.isEmpty() const QString targetName = mcuTarget->platform().displayName.isEmpty()
? mcuTarget->platform().name ? mcuTarget->platform().name
: mcuTarget->platform().displayName; : mcuTarget->platform().displayName;
return QString::fromLatin1("Qt for MCUs %1.%2 - %3%4%5") return QString::fromLatin1("Qt for MCUs %1.%2 - %3%4%5%6")
.arg(QString::number(mcuTarget->qulVersion().majorVersion()), .arg(QString::number(mcuTarget->qulVersion().majorVersion()),
QString::number(mcuTarget->qulVersion().minorVersion()), QString::number(mcuTarget->qulVersion().minorVersion()),
targetName, targetName,
os, os,
colorDepth); colorDepth,
compilerName);
} }
QList<Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTarget) QList<Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTarget)

View File

@@ -116,7 +116,8 @@ public:
TypeKEIL, TypeKEIL,
TypeGHS, TypeGHS,
TypeMSVC, TypeMSVC,
TypeGCC TypeGCC,
TypeUnsupported
}; };
McuToolChainPackage(const QString &label, McuToolChainPackage(const QString &label,
@@ -128,6 +129,7 @@ public:
Type type() const; Type type() 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 cmakeToolChainFileName() const; QString cmakeToolChainFileName() const;
QVariant debuggerId() const; QVariant debuggerId() const;

View File

@@ -27,6 +27,9 @@
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include <baremetal/baremetalconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
@@ -78,6 +81,11 @@ static McuToolChainPackage *createGccToolChainPackage()
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::TypeGCC); return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::TypeGCC);
} }
static McuToolChainPackage *createUnsupportedToolChainPackage()
{
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::TypeUnsupported);
}
static McuToolChainPackage *createArmGccPackage() static McuToolChainPackage *createArmGccPackage()
{ {
const char envVar[] = "ARMGCC_DIR"; const char envVar[] = "ARMGCC_DIR";
@@ -126,6 +134,36 @@ static McuToolChainPackage *createGhsToolchainPackage()
return result; return result;
} }
static McuToolChainPackage *createIarToolChainPackage()
{
const char envVar[] = "IAR_ARM_COMPILER_DIR";
QString defaultPath;
if (qEnvironmentVariableIsSet(envVar))
defaultPath = qEnvironmentVariable(envVar);
else {
const ProjectExplorer::ToolChain *tc =
ProjectExplorer::ToolChainManager::toolChain([](const ProjectExplorer::ToolChain *t) {
return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
});
if (tc) {
const Utils::FilePath compilerExecPath = tc->compilerCommand();
defaultPath = compilerExecPath.parentDir().parentDir().toString();
}
else
defaultPath = QDir::homePath();
}
auto result = new McuToolChainPackage(
"IAR ARM Compiler",
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/iccarm"),
"IARToolchain",
McuToolChainPackage::TypeIAR);
result->setEnvironmentVariableName(envVar);
return result;
}
static McuPackage *createRGLPackage() static McuPackage *createRGLPackage()
{ {
const char envVar[] = "RGL_DIR"; const char envVar[] = "RGL_DIR";
@@ -321,6 +359,8 @@ protected:
{ {
QVector<McuTarget *> mcuTargets; QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId); McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
if (!tcPkg)
tcPkg = createUnsupportedToolChainPackage();
for (auto os : {McuTarget::OS::BareMetal, McuTarget::OS::FreeRTOS}) { for (auto os : {McuTarget::OS::BareMetal, McuTarget::OS::FreeRTOS}) {
for (int colorDepth : desc.colorDepths) { for (int colorDepth : desc.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs = { tcPkg }; QVector<McuPackage*> required3rdPartyPkgs = { tcPkg };
@@ -366,6 +406,8 @@ protected:
QVector<McuTarget *> createDesktopTargetsLegacy(const McuTargetDescription& desc) QVector<McuTarget *> createDesktopTargetsLegacy(const McuTargetDescription& desc)
{ {
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId); McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
if (!tcPkg)
tcPkg = createUnsupportedToolChainPackage();
const auto platform = McuTarget::Platform{ desc.platform, desc.platformName, desc.platformVendor }; const auto platform = McuTarget::Platform{ desc.platform, desc.platformName, desc.platformVendor };
auto desktopTarget = new McuTarget(QVersionNumber::fromString(desc.qulVersion), auto desktopTarget = new McuTarget(QVersionNumber::fromString(desc.qulVersion),
platform, McuTarget::OS::Desktop, {}, tcPkg); platform, McuTarget::OS::Desktop, {}, tcPkg);
@@ -385,10 +427,14 @@ protected:
QVector<McuTarget *> mcuTargets; QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId); McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
if (!tcPkg)
tcPkg = createUnsupportedToolChainPackage();
for (int colorDepth : desc.colorDepths) { for (int colorDepth : desc.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs; QVector<McuPackage*> 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::TypeUnsupported)
required3rdPartyPkgs.append(tcPkg); required3rdPartyPkgs.append(tcPkg);
// Add setting specific to platform IDE // Add setting specific to platform IDE
@@ -440,6 +486,7 @@ static QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescrip
const QHash<QString, McuToolChainPackage *> tcPkgs = { const QHash<QString, McuToolChainPackage *> tcPkgs = {
{{"armgcc"}, createArmGccPackage()}, {{"armgcc"}, createArmGccPackage()},
{{"greenhills"}, createGhsToolchainPackage()}, {{"greenhills"}, createGhsToolchainPackage()},
{{"iar"}, createIarToolChainPackage()},
{{"msvc"}, createMsvcToolChainPackage()}, {{"msvc"}, createMsvcToolChainPackage()},
{{"gcc"}, createGccToolChainPackage()}, {{"gcc"}, createGccToolChainPackage()},
}; };