McuSupport: Automatic memory management for mcu sdk

Fix crash while automatically restoring kits during startup.
Change packages container to set to avoid duplicates.
Use RAII for McuSdkRepository.

Change-Id: I4b3f4156f0bc770c8a5ea8a171b1f22f6ffb8f96
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Piotr Mućko
2022-03-28 16:42:51 +02:00
parent 652f130fae
commit a3fbfac814
19 changed files with 229 additions and 265 deletions

View File

@@ -45,6 +45,8 @@ public:
ValidPackage ValidPackage
}; };
virtual ~McuAbstractPackage() = default;
virtual QString label() const = 0; virtual QString label() const = 0;
virtual const QString &cmakeVariableName() const = 0; virtual const QString &cmakeVariableName() const = 0;
virtual const QString &environmentVariableName() const = 0; virtual const QString &environmentVariableName() const = 0;

View File

@@ -34,9 +34,6 @@
namespace McuSupport::Internal { namespace McuSupport::Internal {
class McuAbstractPackage;
class McuToolChainPackage;
namespace Sdk { namespace Sdk {
struct McuTargetDescription; struct McuTargetDescription;
@@ -44,11 +41,11 @@ class McuAbstractTargetFactory
{ {
public: public:
using Ptr = std::unique_ptr<McuAbstractTargetFactory>; using Ptr = std::unique_ptr<McuAbstractTargetFactory>;
~McuAbstractTargetFactory() = default; virtual ~McuAbstractTargetFactory() = default;
virtual QPair<Targets, Packages> createTargets(const McuTargetDescription &) = 0; virtual QPair<Targets, Packages> createTargets(const McuTargetDescription &) = 0;
using AdditionalPackages using AdditionalPackages
= QPair<QHash<QString, McuToolChainPackage *>, QHash<QString, McuAbstractPackage *>>; = QPair<QHash<QString, McuToolChainPackagePtr>, QHash<QString, McuPackagePtr>>;
virtual AdditionalPackages getAdditionalPackages() const { return {}; } virtual AdditionalPackages getAdditionalPackages() const { return {}; }
}; // struct McuAbstractTargetFactory }; // struct McuAbstractTargetFactory
} // namespace Sdk } // namespace Sdk

View File

@@ -81,7 +81,7 @@ static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation c
class McuKitFactory class McuKitFactory
{ {
public: public:
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) static void setKitToolchains(Kit *k, const McuToolChainPackagePtr &tcPackage)
{ {
switch (tcPackage->toolchainType()) { switch (tcPackage->toolchainType()) {
case McuToolChainPackage::ToolChainType::Unsupported: case McuToolChainPackage::ToolChainType::Unsupported:
@@ -143,7 +143,7 @@ public:
k->setIrrelevantAspects(irrelevant); k->setIrrelevantAspects(irrelevant);
} }
static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage) static void setKitDebugger(Kit *k, const McuToolChainPackagePtr &tcPackage)
{ {
if (tcPackage->isDesktopToolchain()) { if (tcPackage->isDesktopToolchain()) {
// 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
@@ -184,16 +184,16 @@ public:
static void setKitDependencies(Kit *k, static void setKitDependencies(Kit *k,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage) const McuPackagePtr &qtForMCUsSdkPackage)
{ {
NameValueItems dependencies; NameValueItems dependencies;
auto processPackage = [&dependencies](const McuAbstractPackage *package) { auto processPackage = [&dependencies](const McuPackagePtr &package) {
const auto cmakeVariableName = package->cmakeVariableName(); const auto cmakeVariableName = package->cmakeVariableName();
if (!cmakeVariableName.isEmpty()) if (!cmakeVariableName.isEmpty())
dependencies.append({cmakeVariableName, package->detectionPath().toUserOutput()}); dependencies.append({cmakeVariableName, package->detectionPath().toUserOutput()});
}; };
for (auto package : mcuTarget->packages()) for (const auto &package : mcuTarget->packages())
processPackage(package); processPackage(package);
processPackage(qtForMCUsSdkPackage); processPackage(qtForMCUsSdkPackage);
@@ -206,7 +206,7 @@ public:
static void setKitEnvironment(Kit *k, static void setKitEnvironment(Kit *k,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage) const McuPackagePtr &qtForMCUsSdkPackage)
{ {
EnvironmentItems changes; EnvironmentItems changes;
QStringList pathAdditions; // clazy:exclude=inefficient-qlist-soft QStringList pathAdditions; // clazy:exclude=inefficient-qlist-soft
@@ -218,12 +218,12 @@ public:
&& !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi()) && !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi())
pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput()); pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput());
auto processPackage = [&pathAdditions](const McuAbstractPackage *package) { auto processPackage = [&pathAdditions](const McuPackagePtr &package) {
if (package->isAddToSystemPath()) if (package->isAddToSystemPath())
pathAdditions.append(package->path().toUserOutput()); pathAdditions.append(package->path().toUserOutput());
}; };
for (auto package : mcuTarget->packages()) for (const auto &package : mcuTarget->packages())
processPackage(package); processPackage(package);
processPackage(qtForMCUsSdkPackage); processPackage(qtForMCUsSdkPackage);
@@ -241,7 +241,7 @@ public:
static void setKitCMakeOptions(Kit *k, static void setKitCMakeOptions(Kit *k,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage) const McuPackagePtr &qtForMCUsSdkPackage)
{ {
using namespace CMakeProjectManager; using namespace CMakeProjectManager;
auto configMap = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(k)); auto configMap = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(k));
@@ -298,7 +298,7 @@ public:
} }
} }
auto processPackage = [&configMap](const McuAbstractPackage *package) { auto processPackage = [&configMap](const McuPackagePtr &package) {
if (!package->cmakeVariableName().isEmpty()) if (!package->cmakeVariableName().isEmpty())
configMap.insert(package->cmakeVariableName().toUtf8(), configMap.insert(package->cmakeVariableName().toUtf8(),
package->path().toUserOutput().toUtf8()); package->path().toUserOutput().toUtf8());
@@ -321,9 +321,9 @@ public:
}; // class McuKitFactory }; // class McuKitFactory
// Construct kit // Construct kit
Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk) Kit *newKit(const McuTarget *mcuTarget, const McuPackagePtr &qtForMCUsSdk)
{ {
const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) { const auto init = [&mcuTarget, qtForMCUsSdk](Kit *k) {
KitGuard kitGuard(k); KitGuard kitGuard(k);
McuKitFactory::setKitProperties(generateKitNameFromTarget(mcuTarget), McuKitFactory::setKitProperties(generateKitNameFromTarget(mcuTarget),
@@ -348,7 +348,7 @@ Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
// Kit Information // Kit Information
QString generateKitNameFromTarget(const McuTarget *mcuTarget) QString generateKitNameFromTarget(const McuTarget *mcuTarget)
{ {
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage(); McuToolChainPackagePtr tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain() const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
? QString::fromLatin1(" (%1)").arg( ? QString::fromLatin1(" (%1)").arg(
tcPkg->toolChainName().toUpper()) tcPkg->toolChainName().toUpper())
@@ -389,7 +389,7 @@ static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
// Kit Information // Kit Information
bool kitIsUpToDate(const Kit *kit, bool kitIsUpToDate(const Kit *kit,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage) const McuPackagePtr &qtForMCUsSdkPackage)
{ {
return kitQulVersion(kit) == mcuTarget->qulVersion() return kitQulVersion(kit) == mcuTarget->qulVersion()
&& kitDependencyPath(kit, qtForMCUsSdkPackage->cmakeVariableName()).toUserOutput() && kitDependencyPath(kit, qtForMCUsSdkPackage->cmakeVariableName()).toUserOutput()
@@ -414,18 +414,17 @@ QList<Kit *> existingKits(const McuTarget *mcuTarget)
} }
// Queries // Queries
QList<Kit *> matchingKits(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage) QList<Kit *> matchingKits(const McuTarget *mcuTarget, const McuPackagePtr &qtForMCUsSdkPackage)
{ {
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) { return Utils::filtered(existingKits(mcuTarget), [&mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage); return kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
}); });
} }
// Queries // Queries
QList<Kit *> upgradeableKits(const McuTarget *mcuTarget, QList<Kit *> upgradeableKits(const McuTarget *mcuTarget, const McuPackagePtr &qtForMCUsSdkPackage)
const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) { return Utils::filtered(existingKits(mcuTarget), [&mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return !kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage); return !kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
}); });
} }
@@ -433,10 +432,10 @@ QList<Kit *> upgradeableKits(const McuTarget *mcuTarget,
// Queries // Queries
QList<Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget) QList<Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget)
{ {
return Utils::filtered(existingKits(mcuTarget), [mcuTarget](Kit *kit) { return Utils::filtered(existingKits(mcuTarget), [&mcuTarget](Kit *kit) {
const auto entries = Utils::NameValueDictionary( const auto entries = Utils::NameValueDictionary(
McuDependenciesKitAspect::configuration(kit)); McuDependenciesKitAspect::configuration(kit));
return Utils::anyOf(mcuTarget->packages(), [&entries](const McuAbstractPackage *package) { return Utils::anyOf(mcuTarget->packages(), [&entries](const McuPackagePtr &package) {
const QString cmakeVariableName = package->cmakeVariableName(); const QString cmakeVariableName = package->cmakeVariableName();
return !cmakeVariableName.isEmpty() return !cmakeVariableName.isEmpty()
&& entries.value(cmakeVariableName) != package->path().toUserOutput(); && entries.value(cmakeVariableName) != package->path().toUserOutput();
@@ -456,7 +455,7 @@ QList<Kit *> outdatedKits()
// Maintenance // Maintenance
void createAutomaticKits() void createAutomaticKits()
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); McuPackagePtr qtForMCUsPackage{Sdk::createQtForMCUsPackage()};
const auto createKits = [qtForMCUsPackage]() { const auto createKits = [qtForMCUsPackage]() {
if (McuSupportOptions::automaticKitCreationFromSettings()) { if (McuSupportOptions::automaticKitCreationFromSettings()) {
@@ -501,34 +500,29 @@ void createAutomaticKits()
} }
FilePath dir = qtForMCUsPackage->path(); FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo; McuSdkRepository repo{Sdk::targetsAndPackages(dir)};
Sdk::targetsAndPackages(dir, &repo);
bool needsUpgrade = false; bool needsUpgrade = false;
for (const auto &target : qAsConst(repo.mcuTargets)) { for (const auto &target : qAsConst(repo.mcuTargets)) {
// if kit already exists, skip // if kit already exists, skip
if (!matchingKits(target, qtForMCUsPackage).empty()) if (!matchingKits(target.get(), qtForMCUsPackage).empty())
continue; continue;
if (!upgradeableKits(target, qtForMCUsPackage).empty()) { if (!upgradeableKits(target.get(), qtForMCUsPackage).empty()) {
// if kit exists but wrong version/path // if kit exists but wrong version/path
needsUpgrade = true; needsUpgrade = true;
} else { } else {
// if no kits for this target, create // if no kits for this target, create
if (target->isValid()) if (target->isValid())
newKit(target, qtForMCUsPackage); newKit(target.get(), qtForMCUsPackage);
target->printPackageProblems(); target->printPackageProblems();
} }
} }
repo.deletePackagesAndTargets();
if (needsUpgrade) if (needsUpgrade)
McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade(); McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade();
} }
}; };
createKits(); createKits();
delete qtForMCUsPackage;
} }
// Maintenance // Maintenance
@@ -541,18 +535,17 @@ void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
if (upgradeOption == UpgradeOption::Ignore) if (upgradeOption == UpgradeOption::Ignore)
return; return;
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); McuPackagePtr qtForMCUsPackage{Sdk::createQtForMCUsPackage()};
auto dir = qtForMCUsPackage->path(); auto dir = qtForMCUsPackage->path();
McuSdkRepository repo; McuSdkRepository repo{Sdk::targetsAndPackages(dir)};
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) { for (const auto &target : qAsConst(repo.mcuTargets)) {
if (!matchingKits(target, qtForMCUsPackage).empty()) if (!matchingKits(target.get(), qtForMCUsPackage).empty())
// already up-to-date // already up-to-date
continue; continue;
const auto kits = upgradeableKits(target, qtForMCUsPackage); const auto kits = upgradeableKits(target.get(), qtForMCUsPackage);
if (!kits.empty()) { if (!kits.empty()) {
if (upgradeOption == UpgradeOption::Replace) { if (upgradeOption == UpgradeOption::Replace) {
for (auto existingKit : kits) for (auto existingKit : kits)
@@ -560,13 +553,10 @@ void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
} }
if (target->isValid()) if (target->isValid())
newKit(target, qtForMCUsPackage); newKit(target.get(), qtForMCUsPackage);
target->printPackageProblems(); target->printPackageProblems();
} }
} }
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
} }
// Maintenance // Maintenance
@@ -574,7 +564,7 @@ void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
// button is available if SDK version changed // button is available if SDK version changed
void upgradeKitInPlace(ProjectExplorer::Kit *kit, void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk) const McuPackagePtr &qtForMCUsSdk)
{ {
McuKitFactory::setKitProperties(generateKitNameFromTarget(mcuTarget), McuKitFactory::setKitProperties(generateKitNameFromTarget(mcuTarget),
kit, kit,
@@ -590,24 +580,23 @@ void upgradeKitInPlace(ProjectExplorer::Kit *kit,
// update the corresponding cmake variables in all existing kits // update the corresponding cmake variables in all existing kits
void updatePathsInExistingKits() void updatePathsInExistingKits()
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); McuPackagePtr qtForMCUsPackage{Sdk::createQtForMCUsPackage()};
FilePath dir = qtForMCUsPackage->path(); FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo; McuSdkRepository repo{Sdk::targetsAndPackages(dir)};
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) { for (const auto &target : qAsConst(repo.mcuTargets)) {
if (target->isValid()) { if (target->isValid()) {
for (auto *kit : kitsWithMismatchedDependencies(target)) { for (auto *kit : kitsWithMismatchedDependencies(target.get())) {
auto changes = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(kit)); auto changes = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(kit));
const auto updateForPackage = [&changes](const McuAbstractPackage *package) { const auto updateForPackage = [&changes](const McuPackagePtr &package) {
if (!package->cmakeVariableName().isEmpty() && package->isValidStatus()) { if (!package->cmakeVariableName().isEmpty() && package->isValidStatus()) {
changes.insert(package->cmakeVariableName().toUtf8(), changes.insert(package->cmakeVariableName().toUtf8(),
package->path().toUserOutput().toUtf8()); package->path().toUserOutput().toUtf8());
} }
}; };
for (auto package : target->packages()) { for (const auto &package : target->packages()) {
updateForPackage(package); updateForPackage(package);
} }
updateForPackage(qtForMCUsPackage); updateForPackage(qtForMCUsPackage);
@@ -618,9 +607,6 @@ void updatePathsInExistingKits()
} }
} }
} }
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
} }
// Maintenance // Maintenance
@@ -679,23 +665,19 @@ void fixExistingKits()
} }
// Fix kit dependencies for known targets // Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); McuPackagePtr qtForMCUsPackage{Sdk::createQtForMCUsPackage()};
qtForMCUsPackage->updateStatus(); qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->isValidStatus()) { if (qtForMCUsPackage->isValidStatus()) {
FilePath dir = qtForMCUsPackage->path(); FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo; McuSdkRepository repo{Sdk::targetsAndPackages(dir)};
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) for (const auto &target : qAsConst(repo.mcuTargets))
for (auto kit : existingKits(target)) { for (auto kit : existingKits(target.get())) {
if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) { if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) {
McuKitFactory::setKitCMakeOptions(kit, target, qtForMCUsPackage); McuKitFactory::setKitCMakeOptions(kit, target.get(), qtForMCUsPackage);
McuKitFactory::setKitDependencies(kit, target, qtForMCUsPackage); McuKitFactory::setKitDependencies(kit, target.get(), qtForMCUsPackage);
} }
} }
repo.deletePackagesAndTargets();
} }
delete qtForMCUsPackage;
} }
// Maintenance // Maintenance

View File

@@ -35,8 +35,7 @@ namespace ProjectExplorer {
class Kit; class Kit;
} // namespace ProjectExplorer } // namespace ProjectExplorer
namespace McuSupport { namespace McuSupport::Internal {
namespace Internal {
class McuAbstractPackage; class McuAbstractPackage;
class McuTarget; class McuTarget;
@@ -45,21 +44,21 @@ namespace McuKitManager {
enum class UpgradeOption { Ignore, Keep, Replace }; enum class UpgradeOption { Ignore, Keep, Replace };
// Kit Factory // Kit Factory
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk); ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuPackagePtr &qtForMCUsSdk);
// Kit information // Kit information
QString generateKitNameFromTarget(const McuTarget *mcuTarget); QString generateKitNameFromTarget(const McuTarget *mcuTarget);
QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit); QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
bool kitIsUpToDate(const ProjectExplorer::Kit *kit, bool kitIsUpToDate(const ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage); const McuPackagePtr &qtForMCUsSdkPackage);
// Queries // Queries
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget); QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget, QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage); const McuPackagePtr &qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> upgradeableKits(const McuTarget *mcuTarget, QList<ProjectExplorer::Kit *> upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage); const McuPackagePtr &qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget); QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
QList<ProjectExplorer::Kit *> outdatedKits(); QList<ProjectExplorer::Kit *> outdatedKits();
@@ -68,7 +67,7 @@ void createAutomaticKits();
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption); void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption);
void upgradeKitInPlace(ProjectExplorer::Kit *kit, void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk); const McuPackagePtr &qtForMCUsSdk);
// Fixing kits: // Fixing kits:
void updatePathsInExistingKits(); void updatePathsInExistingKits();
@@ -78,7 +77,6 @@ void fixExistingKits();
void removeOutdatedKits(); void removeOutdatedKits();
} // namespace McuKitManager } // namespace McuKitManager
} // namespace Internal } // namespace McuSupport::Internal
} // namespace McuSupport
Q_DECLARE_METATYPE(McuSupport::Internal::McuKitManager::UpgradeOption) Q_DECLARE_METATYPE(McuSupport::Internal::McuKitManager::UpgradeOption)

View File

@@ -239,10 +239,7 @@ bool McuPackage::writeToSettings() const
QWidget *McuPackage::widget() QWidget *McuPackage::widget()
{ {
if (m_widget) auto *widget = new QWidget;
return m_widget;
m_widget = new QWidget;
m_fileChooser = new PathChooser; m_fileChooser = new PathChooser;
m_fileChooser->lineEdit()->setButtonIcon(FancyLineEdit::Right, Icons::RESET.icon()); m_fileChooser->lineEdit()->setButtonIcon(FancyLineEdit::Right, Icons::RESET.icon());
m_fileChooser->lineEdit()->setButtonVisible(FancyLineEdit::Right, true); m_fileChooser->lineEdit()->setButtonVisible(FancyLineEdit::Right, true);
@@ -250,7 +247,7 @@ QWidget *McuPackage::widget()
m_fileChooser->setFilePath(m_defaultPath); m_fileChooser->setFilePath(m_defaultPath);
}); });
auto layout = new QGridLayout(m_widget); auto layout = new QGridLayout(widget);
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
m_infoLabel = new InfoLabel(); m_infoLabel = new InfoLabel();
@@ -277,7 +274,7 @@ QWidget *McuPackage::widget()
}); });
updateStatus(); updateStatus();
return m_widget; return widget;
} }
McuToolChainPackage::McuToolChainPackage(const QString &label, McuToolChainPackage::McuToolChainPackage(const QString &label,

View File

@@ -64,6 +64,8 @@ public:
const bool addToPath = false, const bool addToPath = false,
const Utils::FilePath &relativePathModifier = Utils::FilePath()); const Utils::FilePath &relativePathModifier = Utils::FilePath());
~McuPackage() override = default;
QString label() const override; QString label() const override;
const QString &cmakeVariableName() const override; const QString &cmakeVariableName() const override;
const QString &environmentVariableName() const override; const QString &environmentVariableName() const override;
@@ -89,7 +91,6 @@ private:
void updatePath(); void updatePath();
void updateStatusUi(); void updateStatusUi();
QWidget *m_widget = nullptr;
Utils::PathChooser *m_fileChooser = nullptr; Utils::PathChooser *m_fileChooser = nullptr;
Utils::InfoLabel *m_infoLabel = nullptr; Utils::InfoLabel *m_infoLabel = nullptr;
@@ -113,6 +114,7 @@ private:
class McuToolChainPackage : public McuPackage class McuToolChainPackage : public McuPackage
{ {
Q_OBJECT
public: public:
enum class ToolChainType { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported }; enum class ToolChainType { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported };

View File

@@ -25,9 +25,10 @@
#pragma once #pragma once
#include <QtGlobal>
#include <QList> #include <QList>
#include <QSharedPointer>
#include <QVersionNumber> #include <QVersionNumber>
#include <QtGlobal>
#if defined(MCUSUPPORT_LIBRARY) #if defined(MCUSUPPORT_LIBRARY)
#define MCUSUPPORTSHARED_EXPORT Q_DECL_EXPORT #define MCUSUPPORTSHARED_EXPORT Q_DECL_EXPORT
@@ -39,9 +40,14 @@ namespace McuSupport::Internal {
class McuTarget; class McuTarget;
class McuAbstractPackage; class McuAbstractPackage;
class McuToolChainPackage;
using Targets = QList<McuTarget*>; using McuPackagePtr = QSharedPointer<McuAbstractPackage>;
using Packages = QList<McuAbstractPackage*>; using McuToolChainPackagePtr = QSharedPointer<McuToolChainPackage>;
static const QVersionNumber legacyVersion {2, 0, 0}; using McuTargetPtr = QSharedPointer<McuTarget>;
} using Targets = QList<McuTargetPtr>;
using Packages = QSet<McuPackagePtr>;
static const QVersionNumber legacyVersion{2, 0, 0};
} // namespace McuSupport::Internal

View File

@@ -45,38 +45,28 @@
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect;
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace McuSupport { namespace McuSupport::Internal {
namespace Internal {
void McuSdkRepository::deletePackagesAndTargets() namespace {
{ const QString automaticKitCreationSettingsKey = QLatin1String(Constants::SETTINGS_GROUP) + '/'
qDeleteAll(packages); + QLatin1String(
packages.clear(); Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
mcuTargets.clear();
} }
McuSupportOptions::McuSupportOptions(QObject *parent) McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent) : QObject(parent)
, qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage()) , qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage())
{ {
connect(qtForMCUsSdkPackage, connect(qtForMCUsSdkPackage.get(),
&McuAbstractPackage::changed, &McuAbstractPackage::changed,
this, this,
&McuSupportOptions::populatePackagesAndTargets); &McuSupportOptions::populatePackagesAndTargets);
m_automaticKitCreation = automaticKitCreationFromSettings(); m_automaticKitCreation = automaticKitCreationFromSettings();
} }
McuSupportOptions::~McuSupportOptions()
{
deletePackagesAndTargets();
delete qtForMCUsSdkPackage;
}
void McuSupportOptions::populatePackagesAndTargets() void McuSupportOptions::populatePackagesAndTargets()
{ {
setQulDir(qtForMCUsSdkPackage->path()); setQulDir(qtForMCUsSdkPackage->path());
@@ -129,12 +119,16 @@ const QVersionNumber &McuSupportOptions::minimalQulVersion()
void McuSupportOptions::setQulDir(const FilePath &dir) void McuSupportOptions::setQulDir(const FilePath &dir)
{ {
deletePackagesAndTargets();
qtForMCUsSdkPackage->updateStatus(); qtForMCUsSdkPackage->updateStatus();
if (qtForMCUsSdkPackage->isValidStatus()) if (qtForMCUsSdkPackage->isValidStatus())
Sdk::targetsAndPackages(dir, &sdkRepository); sdkRepository = Sdk::targetsAndPackages(dir);
else
sdkRepository = McuSdkRepository{};
for (const auto &package : qAsConst(sdkRepository.packages)) for (const auto &package : qAsConst(sdkRepository.packages))
connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::packagesChanged); connect(package.get(),
&McuAbstractPackage::changed,
this,
&McuSupportOptions::packagesChanged);
emit packagesChanged(); emit packagesChanged();
} }
@@ -167,19 +161,14 @@ McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades()
return McuKitManager::UpgradeOption::Ignore; return McuKitManager::UpgradeOption::Ignore;
} }
void McuSupportOptions::deletePackagesAndTargets()
{
sdkRepository.deletePackagesAndTargets();
}
void McuSupportOptions::checkUpgradeableKits() void McuSupportOptions::checkUpgradeableKits()
{ {
if (!qtForMCUsSdkPackage->isValidStatus() || sdkRepository.mcuTargets.size() == 0) if (!qtForMCUsSdkPackage->isValidStatus() || sdkRepository.mcuTargets.isEmpty())
return; return;
if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) { if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTargetPtr &target) {
return !McuKitManager::upgradeableKits(target, this->qtForMCUsSdkPackage).empty() return !McuKitManager::upgradeableKits(target.get(), this->qtForMCUsSdkPackage).empty()
&& McuKitManager::matchingKits(target, this->qtForMCUsSdkPackage).empty(); && McuKitManager::matchingKits(target.get(), this->qtForMCUsSdkPackage).empty();
})) }))
McuKitManager::upgradeKitsByCreatingNewPackage(askForKitUpgrades()); McuKitManager::upgradeKitsByCreatingNewPackage(askForKitUpgrades());
} }
@@ -203,20 +192,15 @@ void McuSupportOptions::setAutomaticKitCreationEnabled(const bool enabled)
void McuSupportOptions::writeGeneralSettings() const void McuSupportOptions::writeGeneralSettings() const
{ {
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
QSettings *settings = Core::ICore::settings(QSettings::UserScope); QSettings *settings = Core::ICore::settings(QSettings::UserScope);
settings->setValue(key, m_automaticKitCreation); settings->setValue(automaticKitCreationSettingsKey, m_automaticKitCreation);
} }
bool McuSupportOptions::automaticKitCreationFromSettings() bool McuSupportOptions::automaticKitCreationFromSettings()
{ {
QSettings *settings = Core::ICore::settings(QSettings::UserScope); QSettings *settings = Core::ICore::settings(QSettings::UserScope);
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/' const bool automaticKitCreation = settings->value(automaticKitCreationSettingsKey, true).toBool();
+ QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
const bool automaticKitCreation = settings->value(key, true).toBool();
return automaticKitCreation; return automaticKitCreation;
} }
} // namespace Internal } // namespace McuSupport::Internal
} // namespace McuSupport

View File

@@ -51,23 +51,21 @@ namespace Internal {
class McuAbstractPackage; class McuAbstractPackage;
class McuSdkRepository class McuSdkRepository final
{ {
public: public:
Packages packages;
Targets mcuTargets; Targets mcuTargets;
void deletePackagesAndTargets(); Packages packages;
}; };
class McuSupportOptions : public QObject class McuSupportOptions final : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit McuSupportOptions(QObject *parent = nullptr); explicit McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override;
McuAbstractPackage *qtForMCUsSdkPackage = nullptr; McuPackagePtr qtForMCUsSdkPackage{nullptr};
McuSdkRepository sdkRepository; McuSdkRepository sdkRepository;
void setQulDir(const Utils::FilePath &dir); void setQulDir(const Utils::FilePath &dir);
@@ -90,8 +88,6 @@ public:
static bool automaticKitCreationFromSettings(); static bool automaticKitCreationFromSettings();
private: private:
void deletePackagesAndTargets();
bool m_automaticKitCreation = true; bool m_automaticKitCreation = true;
signals: signals:
void packagesChanged(); void packagesChanged();

View File

@@ -51,8 +51,7 @@
#include <QPushButton> #include <QPushButton>
#include <QVBoxLayout> #include <QVBoxLayout>
namespace McuSupport { namespace McuSupport::Internal {
namespace Internal {
class McuSupportOptionsWidget : public Core::IOptionsPageWidget class McuSupportOptionsWidget : public Core::IOptionsPageWidget
{ {
@@ -63,7 +62,7 @@ public:
void updateStatus(); void updateStatus();
void showMcuTargetPackages(); void showMcuTargetPackages();
McuTarget *currentMcuTarget() const; McuTargetPtr currentMcuTarget() const;
private: private:
void apply() final; void apply() final;
@@ -73,8 +72,8 @@ private:
QString m_armGccPath; QString m_armGccPath;
McuSupportOptions m_options; McuSupportOptions m_options;
QMap<McuPackage *, QWidget *> m_packageWidgets; QMap<McuPackagePtr, QWidget *> m_packageWidgets;
QMap<McuTarget *, QWidget *> m_mcuTargetPacketWidgets; QMap<McuTargetPtr, QWidget *> m_mcuTargetPacketWidgets;
QFormLayout *m_packagesLayout = nullptr; QFormLayout *m_packagesLayout = nullptr;
QGroupBox *m_qtForMCUsSdkGroupBox = nullptr; QGroupBox *m_qtForMCUsSdkGroupBox = nullptr;
QGroupBox *m_packagesGroupBox = nullptr; QGroupBox *m_packagesGroupBox = nullptr;
@@ -123,7 +122,7 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
&QComboBox::currentTextChanged, &QComboBox::currentTextChanged,
this, this,
&McuSupportOptionsWidget::showMcuTargetPackages); &McuSupportOptionsWidget::showMcuTargetPackages);
connect(m_options.qtForMCUsSdkPackage, connect(m_options.qtForMCUsSdkPackage.get(),
&McuAbstractPackage::changed, &McuAbstractPackage::changed,
this, this,
&McuSupportOptionsWidget::populateMcuTargetsComboBox); &McuSupportOptionsWidget::populateMcuTargetsComboBox);
@@ -161,17 +160,17 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
m_kitCreationPushButton = new QPushButton(tr("Create Kit")); m_kitCreationPushButton = new QPushButton(tr("Create Kit"));
m_kitCreationPushButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_kitCreationPushButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
connect(m_kitCreationPushButton, &QPushButton::clicked, this, [this] { connect(m_kitCreationPushButton, &QPushButton::clicked, this, [this] {
McuKitManager::newKit(currentMcuTarget(), m_options.qtForMCUsSdkPackage); McuKitManager::newKit(currentMcuTarget().get(), m_options.qtForMCUsSdkPackage);
McuSupportOptions::registerQchFiles(); McuSupportOptions::registerQchFiles();
updateStatus(); updateStatus();
}); });
m_kitUpdatePushButton = new QPushButton(tr("Update Kit")); m_kitUpdatePushButton = new QPushButton(tr("Update Kit"));
m_kitUpdatePushButton->setSizePolicy(m_kitCreationPushButton->sizePolicy()); m_kitUpdatePushButton->setSizePolicy(m_kitCreationPushButton->sizePolicy());
connect(m_kitUpdatePushButton, &QPushButton::clicked, this, [this] { connect(m_kitUpdatePushButton, &QPushButton::clicked, this, [this] {
for (auto kit : for (auto kit : McuKitManager::upgradeableKits(currentMcuTarget().get(),
McuKitManager::upgradeableKits(currentMcuTarget(), m_options.qtForMCUsSdkPackage)) m_options.qtForMCUsSdkPackage))
McuKitManager::upgradeKitInPlace(kit, McuKitManager::upgradeKitInPlace(kit,
currentMcuTarget(), currentMcuTarget().get(),
m_options.qtForMCUsSdkPackage); m_options.qtForMCUsSdkPackage);
updateStatus(); updateStatus();
}); });
@@ -191,7 +190,7 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
void McuSupportOptionsWidget::updateStatus() void McuSupportOptionsWidget::updateStatus()
{ {
const McuTarget *mcuTarget = currentMcuTarget(); const McuTargetPtr mcuTarget = currentMcuTarget();
const bool cMakeAvailable = !CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty(); const bool cMakeAvailable = !CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty();
@@ -222,11 +221,12 @@ void McuSupportOptionsWidget::updateStatus()
m_kitCreationPushButton->setVisible(mcuTargetValid); m_kitCreationPushButton->setVisible(mcuTargetValid);
m_kitUpdatePushButton->setVisible(mcuTargetValid); m_kitUpdatePushButton->setVisible(mcuTargetValid);
if (mcuTargetValid) { if (mcuTargetValid) {
const bool hasMatchingKits const bool hasMatchingKits = !McuKitManager::matchingKits(mcuTarget.get(),
= !McuKitManager::matchingKits(mcuTarget, m_options.qtForMCUsSdkPackage).isEmpty(); m_options.qtForMCUsSdkPackage)
.isEmpty();
const bool hasUpgradeableKits const bool hasUpgradeableKits
= !hasMatchingKits = !hasMatchingKits
&& !McuKitManager::upgradeableKits(mcuTarget, m_options.qtForMCUsSdkPackage) && !McuKitManager::upgradeableKits(mcuTarget.get(), m_options.qtForMCUsSdkPackage)
.isEmpty(); .isEmpty();
m_kitCreationPushButton->setEnabled(!hasMatchingKits); m_kitCreationPushButton->setEnabled(!hasMatchingKits);
@@ -263,7 +263,7 @@ void McuSupportOptionsWidget::updateStatus()
void McuSupportOptionsWidget::showMcuTargetPackages() void McuSupportOptionsWidget::showMcuTargetPackages()
{ {
const McuTarget *mcuTarget = currentMcuTarget(); McuTargetPtr mcuTarget = currentMcuTarget();
if (!mcuTarget) if (!mcuTarget)
return; return;
@@ -273,7 +273,7 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
row.fieldItem->widget()->hide(); row.fieldItem->widget()->hide();
} }
for (auto package : qAsConst(m_options.sdkRepository.packages)) { for (const auto &package : qAsConst(m_options.sdkRepository.packages)) {
QWidget *packageWidget = package->widget(); QWidget *packageWidget = package->widget();
if (!mcuTarget->packages().contains(package)) if (!mcuTarget->packages().contains(package))
continue; continue;
@@ -284,12 +284,14 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
updateStatus(); updateStatus();
} }
McuTarget *McuSupportOptionsWidget::currentMcuTarget() const McuTargetPtr McuSupportOptionsWidget::currentMcuTarget() const
{ {
const int mcuTargetIndex = m_mcuTargetsComboBox->currentIndex(); const int mcuTargetIndex = m_mcuTargetsComboBox->currentIndex();
return (mcuTargetIndex == -1 || m_options.sdkRepository.mcuTargets.isEmpty()) McuTargetPtr target{nullptr};
? nullptr if (mcuTargetIndex != -1 && !m_options.sdkRepository.mcuTargets.isEmpty())
: m_options.sdkRepository.mcuTargets.at(mcuTargetIndex); target = m_options.sdkRepository.mcuTargets.at(mcuTargetIndex);
return target;
} }
void McuSupportOptionsWidget::showEvent(QShowEvent *event) void McuSupportOptionsWidget::showEvent(QShowEvent *event)
@@ -318,8 +320,8 @@ void McuSupportOptionsWidget::populateMcuTargetsComboBox()
m_options.populatePackagesAndTargets(); m_options.populatePackagesAndTargets();
m_mcuTargetsComboBox->clear(); m_mcuTargetsComboBox->clear();
m_mcuTargetsComboBox->addItems( m_mcuTargetsComboBox->addItems(
Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets, [](McuTarget *t) { Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets, [](const McuTargetPtr &t) {
return McuKitManager::generateKitNameFromTarget(t); return McuKitManager::generateKitNameFromTarget(t.get());
})); }));
updateStatus(); updateStatus();
} }
@@ -332,5 +334,4 @@ McuSupportOptionsPage::McuSupportOptionsPage()
setWidgetCreator([] { return new McuSupportOptionsWidget; }); setWidgetCreator([] { return new McuSupportOptionsWidget; });
} }
} // namespace Internal } // namespace McuSupport::Internal
} // namespace McuSupport

View File

@@ -25,10 +25,10 @@
#include "mcusupportplugin.h" #include "mcusupportplugin.h"
#include "mcukitinformation.h" #include "mcukitinformation.h"
#include "mcukitmanager.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportdevice.h" #include "mcusupportdevice.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcukitmanager.h"
#include "mcusupportoptionspage.h" #include "mcusupportoptionspage.h"
#include "mcusupportrunconfiguration.h" #include "mcusupportrunconfiguration.h"
@@ -52,6 +52,10 @@
using namespace Core; using namespace Core;
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace {
constexpr char setupMcuSupportKits[]{"SetupMcuSupportKits"};
}
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
@@ -114,8 +118,6 @@ void McuSupportPlugin::extensionsInitialized()
void McuSupportPlugin::askUserAboutMcuSupportKitsSetup() void McuSupportPlugin::askUserAboutMcuSupportKitsSetup()
{ {
const char setupMcuSupportKits[] = "SetupMcuSupportKits";
if (!ICore::infoBar()->canInfoBeAdded(setupMcuSupportKits) if (!ICore::infoBar()->canInfoBeAdded(setupMcuSupportKits)
|| McuSupportOptions::qulDirFromSettings().isEmpty() || McuSupportOptions::qulDirFromSettings().isEmpty()
|| !McuKitManager::existingKits(nullptr).isEmpty()) || !McuKitManager::existingKits(nullptr).isEmpty())
@@ -126,7 +128,7 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsSetup()
"To do it later, select Options > Devices > MCU."), "To do it later, select Options > Devices > MCU."),
Utils::InfoBarEntry::GlobalSuppression::Enabled); Utils::InfoBarEntry::GlobalSuppression::Enabled);
// clazy:excludeall=connect-3arg-lambda // clazy:excludeall=connect-3arg-lambda
info.addCustomButton(tr("Create Kits for Qt for MCUs"), [setupMcuSupportKits] { info.addCustomButton(tr("Create Kits for Qt for MCUs"), [] {
ICore::infoBar()->removeInfo(setupMcuSupportKits); ICore::infoBar()->removeInfo(setupMcuSupportKits);
QTimer::singleShot(0, []() { ICore::showOptionsDialog(Constants::SETTINGS_ID); }); QTimer::singleShot(0, []() { ICore::showOptionsDialog(Constants::SETTINGS_ID); });
}); });

View File

@@ -52,7 +52,6 @@
#include <QJsonObject> #include <QJsonObject>
#include <QVariant> #include <QVariant>
#include <ciso646>
#include <memory> #include <memory>
using namespace Utils; using namespace Utils;
@@ -416,22 +415,22 @@ static McuAbstractTargetFactory::Ptr createFactory(bool isLegacy)
{ {
McuAbstractTargetFactory::Ptr result; McuAbstractTargetFactory::Ptr result;
if (isLegacy) { if (isLegacy) {
static const QHash<QString, McuToolChainPackage *> tcPkgs = { static const QHash<QString, McuToolChainPackagePtr> tcPkgs = {
{{"armgcc"}, createArmGccToolchainPackage()}, {{"armgcc"}, McuToolChainPackagePtr{createArmGccToolchainPackage()}},
{{"greenhills"}, createGhsToolchainPackage()}, {{"greenhills"}, McuToolChainPackagePtr{createGhsToolchainPackage()}},
{{"iar"}, createIarToolChainPackage()}, {{"iar"}, McuToolChainPackagePtr{createIarToolChainPackage()}},
{{"msvc"}, createMsvcToolChainPackage()}, {{"msvc"}, McuToolChainPackagePtr{createMsvcToolChainPackage()}},
{{"gcc"}, createGccToolChainPackage()}, {{"gcc"}, McuToolChainPackagePtr{createGccToolChainPackage()}},
{{"arm-greenhills"}, createGhsArmToolchainPackage()}, {{"arm-greenhills"}, McuToolChainPackagePtr{createGhsArmToolchainPackage()}},
}; };
// Note: the vendor name (the key of the hash) is case-sensitive. It has to match the "platformVendor" key in the // Note: the vendor name (the key of the hash) is case-sensitive. It has to match the "platformVendor" key in the
// json file. // json file.
static const QHash<QString, McuAbstractPackage *> vendorPkgs = { static const QHash<QString, McuPackagePtr> vendorPkgs = {
{{"ST"}, createStm32CubeProgrammerPackage()}, {{"ST"}, McuPackagePtr{createStm32CubeProgrammerPackage()}},
{{"NXP"}, createMcuXpressoIdePackage()}, {{"NXP"}, McuPackagePtr{createMcuXpressoIdePackage()}},
{{"CYPRESS"}, createCypressProgrammerPackage()}, {{"CYPRESS"}, McuPackagePtr{createCypressProgrammerPackage()}},
{{"RENESAS"}, createRenesasProgrammerPackage()}, {{"RENESAS"}, McuPackagePtr{createRenesasProgrammerPackage()}},
}; };
result = std::make_unique<McuTargetFactoryLegacy>(tcPkgs, vendorPkgs); result = std::make_unique<McuTargetFactoryLegacy>(tcPkgs, vendorPkgs);
@@ -441,7 +440,7 @@ static McuAbstractTargetFactory::Ptr createFactory(bool isLegacy)
return result; return result;
} }
QPair<Targets, Packages> targetsFromDescriptions(const QList<McuTargetDescription> &descriptions, McuSdkRepository targetsFromDescriptions(const QList<McuTargetDescription> &descriptions,
bool isLegacy) bool isLegacy)
{ {
Targets mcuTargets; Targets mcuTargets;
@@ -451,19 +450,19 @@ QPair<Targets, Packages> targetsFromDescriptions(const QList<McuTargetDescriptio
for (const McuTargetDescription &desc : descriptions) { for (const McuTargetDescription &desc : descriptions) {
auto [targets, packages] = targetFactory->createTargets(desc); auto [targets, packages] = targetFactory->createTargets(desc);
mcuTargets.append(targets); mcuTargets.append(targets);
mcuPackages.append(packages); mcuPackages.unite(packages);
} }
if (isLegacy) { if (isLegacy) {
auto [toolchainPkgs, vendorPkgs]{targetFactory->getAdditionalPackages()}; auto [toolchainPkgs, vendorPkgs]{targetFactory->getAdditionalPackages()};
for (McuAbstractPackage *package : toolchainPkgs) { for (McuToolChainPackagePtr &package : toolchainPkgs) {
mcuPackages.append(package); mcuPackages.insert(package);
} }
for (McuAbstractPackage *package : vendorPkgs) { for (McuPackagePtr &package : vendorPkgs) {
mcuPackages.append(package); mcuPackages.insert(package);
} }
} }
return {mcuTargets, mcuPackages}; return McuSdkRepository{mcuTargets, mcuPackages};
} }
Utils::FilePath kitsPath(const Utils::FilePath &dir) Utils::FilePath kitsPath(const Utils::FilePath &dir)
@@ -587,7 +586,7 @@ bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message)
return false; return false;
} }
void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo) McuSdkRepository targetsAndPackages(const Utils::FilePath &dir)
{ {
QList<McuTargetDescription> descriptions; QList<McuTargetDescription> descriptions;
@@ -637,26 +636,23 @@ void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo)
printMessage(McuTarget::tr("No valid kit descriptions found at %1.") printMessage(McuTarget::tr("No valid kit descriptions found at %1.")
.arg(kitsPath(dir).toUserOutput()), .arg(kitsPath(dir).toUserOutput()),
true); true);
return; return McuSdkRepository{};
} else { } else {
QString deprecationMessage; QString deprecationMessage;
if (checkDeprecatedSdkError(dir, deprecationMessage)) { if (checkDeprecatedSdkError(dir, deprecationMessage)) {
printMessage(deprecationMessage, true); printMessage(deprecationMessage, true);
return; return McuSdkRepository{};
} }
} }
} }
const auto tmpTargetLists = targetsFromDescriptions(descriptions, isLegacy); McuSdkRepository repo = targetsFromDescriptions(descriptions, isLegacy);
repo->mcuTargets = tmpTargetLists.first;
repo->packages = tmpTargetLists.second;
// Keep targets sorted lexicographically // Keep targets sorted lexicographically
std::sort(repo->mcuTargets.begin(), Utils::sort(repo.mcuTargets, [](const McuTargetPtr &lhs, const McuTargetPtr &rhs) {
repo->mcuTargets.end(), return McuKitManager::generateKitNameFromTarget(lhs.get())
[](const McuTarget *lhs, const McuTarget *rhs) { < McuKitManager::generateKitNameFromTarget(rhs.get());
return McuKitManager::generateKitNameFromTarget(lhs)
< McuKitManager::generateKitNameFromTarget(rhs);
}); });
return repo;
} }
FilePath packagePathFromSettings(const QString &settingsKey, FilePath packagePathFromSettings(const QString &settingsKey,

View File

@@ -29,7 +29,6 @@
#include <utils/filepath.h> #include <utils/filepath.h>
#include <QPair>
#include <QSettings> #include <QSettings>
namespace McuSupport::Internal { namespace McuSupport::Internal {
@@ -49,10 +48,10 @@ McuAbstractPackage *createQtForMCUsPackage();
bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message); bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message);
void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo); McuSdkRepository targetsAndPackages(const Utils::FilePath &qulDir);
McuTargetDescription parseDescriptionJson(const QByteArray &); McuTargetDescription parseDescriptionJson(const QByteArray &);
QPair<Targets, Packages> targetsFromDescriptions(const QList<McuTargetDescription> &, bool isLegacy); McuSdkRepository targetsFromDescriptions(const QList<McuTargetDescription> &, bool isLegacy);
Utils::FilePath kitsPath(const Utils::FilePath &dir); Utils::FilePath kitsPath(const Utils::FilePath &dir);

View File

@@ -24,8 +24,8 @@
****************************************************************************/ ****************************************************************************/
#include "mcutarget.h" #include "mcutarget.h"
#include "mcupackage.h"
#include "mcukitmanager.h" #include "mcukitmanager.h"
#include "mcupackage.h"
#include "mcusupportplugin.h" #include "mcusupportplugin.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
@@ -37,8 +37,8 @@ namespace McuSupport::Internal {
McuTarget::McuTarget(const QVersionNumber &qulVersion, McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform, const Platform &platform,
OS os, OS os,
const Packages& packages, const Packages &packages,
const McuToolChainPackage *toolChainPackage, const McuToolChainPackagePtr &toolChainPackage,
int colorDepth) int colorDepth)
: m_qulVersion(qulVersion) : m_qulVersion(qulVersion)
, m_platform(platform) , m_platform(platform)
@@ -48,12 +48,12 @@ McuTarget::McuTarget(const QVersionNumber &qulVersion,
, m_colorDepth(colorDepth) , m_colorDepth(colorDepth)
{} {}
const Packages &McuTarget::packages() const Packages McuTarget::packages() const
{ {
return m_packages; return m_packages;
} }
const McuToolChainPackage *McuTarget::toolChainPackage() const McuToolChainPackagePtr McuTarget::toolChainPackage() const
{ {
return m_toolChainPackage; return m_toolChainPackage;
} }
@@ -63,14 +63,14 @@ McuTarget::OS McuTarget::os() const
return m_os; return m_os;
} }
const McuTarget::Platform &McuTarget::platform() const McuTarget::Platform McuTarget::platform() const
{ {
return m_platform; return m_platform;
} }
bool McuTarget::isValid() const bool McuTarget::isValid() const
{ {
return Utils::allOf(packages(), [](McuAbstractPackage *package) { return Utils::allOf(packages(), [](const McuPackagePtr &package) {
package->updateStatus(); package->updateStatus();
return package->isValidStatus(); return package->isValidStatus();
}); });
@@ -95,7 +95,7 @@ void McuTarget::printPackageProblems() const
} }
} }
const QVersionNumber &McuTarget::qulVersion() const QVersionNumber McuTarget::qulVersion() const
{ {
return m_qulVersion; return m_qulVersion;
} }

View File

@@ -63,14 +63,14 @@ public:
McuTarget(const QVersionNumber &qulVersion, McuTarget(const QVersionNumber &qulVersion,
const Platform &platform, const Platform &platform,
OS os, OS os,
const Packages& packages, const Packages &packages,
const McuToolChainPackage *toolChainPackage, const McuToolChainPackagePtr &toolChainPackage,
int colorDepth = UnspecifiedColorDepth); int colorDepth = UnspecifiedColorDepth);
const QVersionNumber &qulVersion() const; QVersionNumber qulVersion() const;
const Packages &packages() const; Packages packages() const;
const McuToolChainPackage *toolChainPackage() const; McuToolChainPackagePtr toolChainPackage() const;
const Platform &platform() const; Platform platform() const;
OS os() const; OS os() const;
int colorDepth() const; int colorDepth() const;
bool isValid() const; bool isValid() const;
@@ -81,7 +81,7 @@ private:
const Platform m_platform; const Platform m_platform;
const OS m_os; const OS m_os;
const Packages m_packages; const Packages m_packages;
const McuToolChainPackage* m_toolChainPackage; McuToolChainPackagePtr m_toolChainPackage;
const int m_colorDepth; const int m_colorDepth;
}; // class McuTarget }; // class McuTarget

View File

@@ -43,13 +43,15 @@ QPair<Targets, Packages> McuTargetFactory::createTargets(const McuTargetDescript
{desc.platform.id, desc.platform.name, desc.platform.vendor}); {desc.platform.id, desc.platform.name, desc.platform.vendor});
Packages targetPackages = createPackages(desc); Packages targetPackages = createPackages(desc);
packages.append(targetPackages); packages.unite(targetPackages);
mcuTargets.append(new McuTarget{QVersionNumber::fromString(desc.qulVersion), mcuTargets.append(McuTargetPtr{
new McuTarget{QVersionNumber::fromString(desc.qulVersion),
platform, platform,
deduceOperatingSystem(desc), deduceOperatingSystem(desc),
targetPackages, targetPackages,
new McuToolChainPackage{{}, {}, {}, {}, {}}, McuToolChainPackagePtr{new McuToolChainPackage{
colorDepth}); {}, {}, {}, {}, McuToolChainPackage::ToolChainType::Unsupported}},
colorDepth}});
} }
return {mcuTargets, packages}; return {mcuTargets, packages};
} }
@@ -69,14 +71,14 @@ Packages McuTargetFactory::createPackages(const McuTargetDescription &desc)
QList<PackageDescription> packageDescriptions = aggregatePackageEntries(desc); QList<PackageDescription> packageDescriptions = aggregatePackageEntries(desc);
for (const PackageDescription &pkgDesc : packageDescriptions) { for (const PackageDescription &pkgDesc : packageDescriptions) {
packages.append(new McuPackage{ packages.insert(McuPackagePtr{new McuPackage{
pkgDesc.label, pkgDesc.label,
pkgDesc.defaultPath, pkgDesc.defaultPath,
pkgDesc.validationPath, pkgDesc.validationPath,
pkgDesc.setting, pkgDesc.setting,
pkgDesc.cmakeVar, pkgDesc.cmakeVar,
pkgDesc.envVar, pkgDesc.envVar,
}); }});
} }
return packages; return packages;

View File

@@ -38,67 +38,68 @@ namespace McuSupport::Internal::Sdk {
QPair<Targets, Packages> McuTargetFactoryLegacy::createTargets(const McuTargetDescription &desc) QPair<Targets, Packages> McuTargetFactoryLegacy::createTargets(const McuTargetDescription &desc)
{ {
QHash<QString, McuAbstractPackage *> boardSdkPkgs; QHash<QString, McuPackagePtr> boardSdkPkgs;
QHash<QString, McuAbstractPackage *> freeRTOSPkgs; QHash<QString, McuPackagePtr> freeRTOSPkgs;
Targets mcuTargets; Targets mcuTargets;
Packages packages; Packages packages;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id); McuToolChainPackagePtr tcPkg = tcPkgs.value(desc.toolchain.id);
if (tcPkg) { if (tcPkg) {
tcPkg->setVersions(desc.toolchain.versions); tcPkg->setVersions(desc.toolchain.versions);
} else { } else {
tcPkg = createUnsupportedToolChainPackage(); tcPkg.reset(createUnsupportedToolChainPackage());
} }
for (int colorDepth : desc.platform.colorDepths) { for (int colorDepth : desc.platform.colorDepths) {
Packages required3rdPartyPkgs; Packages 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->toolchainType() != McuToolChainPackage::ToolChainType::Unsupported) { && tcPkg->toolchainType() != McuToolChainPackage::ToolChainType::Unsupported) {
required3rdPartyPkgs.append(tcPkg); required3rdPartyPkgs.insert(tcPkg);
} }
// Add setting specific to platform IDE. // Add setting specific to platform IDE.
if (vendorPkgs.contains(desc.platform.vendor)) { if (vendorPkgs.contains(desc.platform.vendor)) {
required3rdPartyPkgs.append(vendorPkgs.value(desc.platform.vendor)); required3rdPartyPkgs.insert(vendorPkgs.value(desc.platform.vendor));
} }
// Board SDK specific settings // Board SDK specific settings
Utils::FilePath boardSdkDefaultPath; Utils::FilePath boardSdkDefaultPath;
if (!desc.boardSdk.envVar.isEmpty()) { if (!desc.boardSdk.envVar.isEmpty()) {
if (!boardSdkPkgs.contains(desc.boardSdk.envVar)) { if (!boardSdkPkgs.contains(desc.boardSdk.envVar)) {
McuAbstractPackage *boardSdkPkg = createBoardSdkPackage(desc); McuPackagePtr boardSdkPkg{createBoardSdkPackage(desc)};
boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg); boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg);
} }
McuAbstractPackage *boardSdkPkg{boardSdkPkgs.value(desc.boardSdk.envVar)}; McuPackagePtr boardSdkPkg{boardSdkPkgs.value(desc.boardSdk.envVar)};
boardSdkPkg->setVersions(desc.boardSdk.versions); boardSdkPkg->setVersions(desc.boardSdk.versions);
boardSdkDefaultPath = boardSdkPkg->defaultPath(); boardSdkDefaultPath = boardSdkPkg->defaultPath();
required3rdPartyPkgs.append(boardSdkPkg); required3rdPartyPkgs.insert(boardSdkPkg);
} }
// Free RTOS specific settings. // Free RTOS specific settings.
if (!desc.freeRTOS.envVar.isEmpty()) { if (!desc.freeRTOS.envVar.isEmpty()) {
if (!freeRTOSPkgs.contains(desc.freeRTOS.envVar)) { if (!freeRTOSPkgs.contains(desc.freeRTOS.envVar)) {
freeRTOSPkgs.insert(desc.freeRTOS.envVar, freeRTOSPkgs.insert(desc.freeRTOS.envVar,
McuPackagePtr{
createFreeRTOSSourcesPackage(desc.freeRTOS.envVar, createFreeRTOSSourcesPackage(desc.freeRTOS.envVar,
boardSdkDefaultPath, boardSdkDefaultPath,
desc.freeRTOS.boardSdkSubDir)); desc.freeRTOS.boardSdkSubDir)});
} }
required3rdPartyPkgs.append(freeRTOSPkgs.value(desc.freeRTOS.envVar)); required3rdPartyPkgs.insert(freeRTOSPkgs.value(desc.freeRTOS.envVar));
} }
packages.append(required3rdPartyPkgs); packages.unite(required3rdPartyPkgs);
const McuTarget::Platform platform( const McuTarget::Platform platform(
{desc.platform.id, desc.platform.name, desc.platform.vendor}); {desc.platform.id, desc.platform.name, desc.platform.vendor});
mcuTargets.push_back(new McuTarget{QVersionNumber::fromString(desc.qulVersion), mcuTargets.push_back(McuTargetPtr{new McuTarget{QVersionNumber::fromString(desc.qulVersion),
platform, platform,
deduceOperatingSystem(desc), deduceOperatingSystem(desc),
required3rdPartyPkgs, required3rdPartyPkgs,
tcPkg, tcPkg,
colorDepth}); colorDepth}});
} }
return {mcuTargets, packages}; return {mcuTargets, packages};
} }
McuTargetFactoryLegacy::AdditionalPackages McuTargetFactoryLegacy::getAdditionalPackages() const McuAbstractTargetFactory::AdditionalPackages McuTargetFactoryLegacy::getAdditionalPackages() const
{ {
return {tcPkgs, vendorPkgs}; return {tcPkgs, vendorPkgs};
} }

View File

@@ -35,20 +35,18 @@ namespace McuSupport::Internal::Sdk {
class McuTargetFactoryLegacy : public McuAbstractTargetFactory class McuTargetFactoryLegacy : public McuAbstractTargetFactory
{ {
public: public:
McuTargetFactoryLegacy(const QHash<QString, McuToolChainPackage *> &tcPkgs, McuTargetFactoryLegacy(const QHash<QString, McuToolChainPackagePtr> &tcPkgs,
const QHash<QString, McuAbstractPackage *> &vendorPkgs) const QHash<QString, McuPackagePtr> &vendorPkgs)
: tcPkgs(tcPkgs) : tcPkgs(tcPkgs)
, vendorPkgs(vendorPkgs) , vendorPkgs(vendorPkgs)
{} {}
QPair<Targets, Packages> createTargets(const McuTargetDescription &) override; QPair<Targets, Packages> createTargets(const McuTargetDescription &) override;
using AdditionalPackages
= QPair<QHash<QString, McuToolChainPackage *>, QHash<QString, McuAbstractPackage *>>;
AdditionalPackages getAdditionalPackages() const override; AdditionalPackages getAdditionalPackages() const override;
private: private:
const QHash<QString, McuToolChainPackage *> tcPkgs; const QHash<QString, McuToolChainPackagePtr> tcPkgs;
const QHash<QString, McuAbstractPackage *> vendorPkgs; const QHash<QString, McuPackagePtr> vendorPkgs;
}; // struct McuTargetFactoryLegacy }; // struct McuTargetFactoryLegacy
} // namespace McuSupport::Internal::Sdk } // namespace McuSupport::Internal::Sdk

View File

@@ -96,34 +96,34 @@ void McuSupportTest::test_parseCmakeEntries()
void McuSupportTest::test_addNewKit() void McuSupportTest::test_addNewKit()
{ {
const QString cmakeVar = "CMAKE_SDK"; const QString cmakeVar = "CMAKE_SDK";
McuPackage sdkPackage{"sdk", // label McuPackagePtr sdkPackage{new McuPackage{"sdk", // label
{}, // defaultPath {}, // defaultPath
{}, // detectionPath {}, // detectionPath
"sdk", // settingsKey "sdk", // settingsKey
cmakeVar, // cmake var cmakeVar, // cmake var
{}}; // env var {}}}; // env var
ProjectExplorer::Kit kit; ProjectExplorer::Kit kit;
McuToolChainPackage McuToolChainPackagePtr toolchainPackage{
toolchainPackage{{}, // label new McuToolChainPackage{{}, // label
{}, // defaultPath {}, // defaultPath
{}, // detectionPath {}, // detectionPath
{}, // settingsKey {}, // settingsKey
McuToolChainPackage::ToolChainType::Unsupported, // toolchain type McuToolChainPackage::ToolChainType::Unsupported, // toolchain type
{}, // cmake var name {}, // cmake var name
{}}; // env var name {}}}; // env var name
const McuTarget::Platform platform{id, name, vendor}; const McuTarget::Platform platform{id, name, vendor};
McuTarget mcuTarget{currentQulVersion, // version McuTarget mcuTarget{currentQulVersion, // version
platform, // platform platform, // platform
McuTarget::OS::FreeRTOS, // os McuTarget::OS::FreeRTOS, // os
{&sdkPackage}, // packages {sdkPackage}, // packages
&toolchainPackage}; // toolchain packages toolchainPackage}; // toolchain packages
auto &kitManager{*KitManager::instance()}; auto &kitManager{*KitManager::instance()};
QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded); QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded);
auto *newKit{McuKitManager::newKit(&mcuTarget, &sdkPackage)}; auto *newKit{McuKitManager::newKit(&mcuTarget, sdkPackage)};
QVERIFY(newKit != nullptr); QVERIFY(newKit != nullptr);
QCOMPARE(kitAddedSpy.count(), 1); QCOMPARE(kitAddedSpy.count(), 1);
@@ -265,10 +265,11 @@ void McuSupportTest::test_createTargetsTheNewWay()
Sdk::McuTargetFactory targetFactory{}; Sdk::McuTargetFactory targetFactory{};
const auto [targets, packages]{targetFactory.createTargets(description)}; const auto [targets, packages]{targetFactory.createTargets(description)};
QVERIFY(not targets.empty()); QVERIFY(not targets.empty());
QCOMPARE(targets.at(0)->colorDepth(), colorDepth); const McuTargetPtr target{*targets.constBegin()};
const auto &tgtPackages{targets.at(0)->packages()}; QCOMPARE(target->colorDepth(), colorDepth);
const auto &tgtPackages{target->packages()};
QVERIFY(not tgtPackages.empty()); QVERIFY(not tgtPackages.empty());
const auto rtosPackage{tgtPackages.first()}; const auto rtosPackage{*tgtPackages.constBegin()};
QCOMPARE(rtosPackage->environmentVariableName(), nxp1064FreeRtosEnvVar); QCOMPARE(rtosPackage->environmentVariableName(), nxp1064FreeRtosEnvVar);
} }