diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index a1b5ec219f1..cfb3dcc3643 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -764,6 +764,27 @@ static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget, EnvironmentKitAspect::setEnvironmentChanges(k, changes); } +static void setKitDependencies(Kit *k, const McuTarget *mcuTarget, + const McuPackage *qtForMCUsSdkPackage) +{ + NameValueItems dependencies; + + auto processPackage = [&dependencies](const McuPackage *package) { + if (!package->environmentVariableName().isEmpty()) + dependencies.append({package->environmentVariableName(), + QDir::toNativeSeparators(package->detectionPath())}); + }; + for (auto package : mcuTarget->packages()) + processPackage(package); + processPackage(qtForMCUsSdkPackage); + + McuDependenciesKitAspect::setDependencies(k, dependencies); + + auto irrelevant = k->irrelevantAspects(); + irrelevant.insert(McuDependenciesKitAspect::id()); + k->setIrrelevantAspects(irrelevant); +} + static void setKitCMakeOptions(Kit *k, const McuTarget* mcuTarget, const QString &qulDir) { using namespace CMakeProjectManager; @@ -886,6 +907,7 @@ Kit *McuSupportOptions::newKit(const McuTarget *mcuTarget, const McuPackage *qtF setKitToolchains(k, mcuTarget->toolChainPackage()); setKitDebugger(k, mcuTarget->toolChainPackage()); setKitEnvironment(k, mcuTarget, qtForMCUsSdk); + setKitDependencies(k, mcuTarget, qtForMCUsSdk); setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk->path()); setKitQtVersionOptions(k); @@ -1006,7 +1028,130 @@ void McuSupportOptions::fixExistingKits() } } } + + // Fix kit dependencies for known targets + auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); + qtForMCUsPackage->updateStatus(); + if (qtForMCUsPackage->validStatus()) { + auto dir = FilePath::fromUserInput(qtForMCUsPackage->path()); + QVector packages; + QVector mcuTargets; + Sdk::targetsAndPackages(dir, &packages, &mcuTargets); + for (auto target: qAsConst(mcuTargets)) + for (auto kit: existingKits(target)) { + if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) { + setKitDependencies(kit, target, qtForMCUsPackage); + } + } + + qDeleteAll(packages); + qDeleteAll(mcuTargets); + } + delete qtForMCUsPackage; } +class McuDependenciesKitAspectWidget final : public KitAspectWidget +{ + Q_DECLARE_TR_FUNCTIONS(McuSupport::McuDependenciesKitAspect) + +public: + McuDependenciesKitAspectWidget(Kit *workingCopy, const KitAspect *ki) + : KitAspectWidget(workingCopy, ki) + { + m_emptyWidget = new QWidget(); + } + + ~McuDependenciesKitAspectWidget() override { + delete m_emptyWidget; + } + void makeReadOnly() override {} + void refresh() override {} + QWidget *mainWidget() const override { + return m_emptyWidget; + } +private: + QWidget *m_emptyWidget; +}; + } // Internal + +McuDependenciesKitAspect::McuDependenciesKitAspect() +{ + setObjectName(QLatin1String("McuDependenciesKitAspect")); + setId(McuDependenciesKitAspect::id()); + setDisplayName(tr("Mcu Dependencies")); + setDescription(tr("Paths to 3rd party dependencies")); + setPriority(28500); +} + +Tasks McuDependenciesKitAspect::validate(const Kit *k) const +{ + Tasks result; + QTC_ASSERT(k, return result); + + const QVariant checkFormat = k->value(McuDependenciesKitAspect::id()); + if (!checkFormat.isNull() && !checkFormat.canConvert(QVariant::List)) + return { BuildSystemTask(Task::Error, tr("The mcu dependencies setting value is invalid.")) }; + + const QVariant envStringList = k->value(EnvironmentKitAspect::id()); + if (!envStringList.isNull() && !envStringList.canConvert(QVariant::List)) + return { BuildSystemTask(Task::Error, tr("The environment setting value is invalid.")) }; + + const auto environment = Utils::NameValueDictionary(envStringList.toStringList()); + for (const auto &dependency: dependencies(k)) { + if (!environment.hasKey(dependency.name)) { + result << BuildSystemTask(Task::Warning, tr("Environment variable %1 not defined.").arg(dependency.name)); + } else { + const auto path = Utils::FilePath::fromString(environment.value(dependency.name) + "/" + dependency.value); + if (!path.exists()) { + result << BuildSystemTask(Task::Warning, tr("%1 not found.").arg(path.toUserOutput())); + } + } + } + + return result; +} + +void McuDependenciesKitAspect::fix(Kit *k) +{ + QTC_ASSERT(k, return); + + const QVariant variant = k->value(McuDependenciesKitAspect::id()); + if (!variant.isNull() && !variant.canConvert(QVariant::List)) { + qWarning("Kit \"%s\" has a wrong mcu dependencies value set.", qPrintable(k->displayName())); + setDependencies(k, Utils::NameValueItems()); + } +} + +KitAspectWidget *McuDependenciesKitAspect::createConfigWidget(Kit *k) const +{ + QTC_ASSERT(k, return nullptr); + return new Internal::McuDependenciesKitAspectWidget(k, this); +} + +KitAspect::ItemList McuDependenciesKitAspect::toUserOutput(const Kit *k) const +{ + Q_UNUSED(k); + return {}; +} + +Utils::Id McuDependenciesKitAspect::id() +{ + return "PE.Profile.McuDependencies"; +} + + +Utils::NameValueItems McuDependenciesKitAspect::dependencies(const Kit *k) +{ + if (k) + return Utils::NameValueItem::fromStringList(k->value(McuDependenciesKitAspect::id()).toStringList()); + return Utils::NameValueItems(); +} + +void McuDependenciesKitAspect::setDependencies(Kit *k, const Utils::NameValueItems &dependencies) +{ + if (k) + k->setValue(McuDependenciesKitAspect::id(), Utils::NameValueItem::toStringList(dependencies)); +} + } // McuSupport diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 33dc340b571..f94a8b5e8c8 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -26,8 +26,10 @@ #pragma once #include "mcusupportversiondetection.h" +#include "mcusupport_global.h" #include +#include #include #include @@ -234,4 +236,24 @@ signals: }; } // namespace Internal + +class MCUSUPPORTSHARED_EXPORT McuDependenciesKitAspect : public ProjectExplorer::KitAspect +{ + Q_OBJECT + +public: + McuDependenciesKitAspect(); + + ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const override; + void fix(ProjectExplorer::Kit *k) override; + + ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; + + ItemList toUserOutput(const ProjectExplorer::Kit *k) const override; + + static Utils::Id id(); + static Utils::NameValueItems dependencies(const ProjectExplorer::Kit *k); + static void setDependencies(ProjectExplorer::Kit *k, const Utils::NameValueItems &dependencies); +}; + } // namespace McuSupport diff --git a/src/plugins/mcusupport/mcusupportplugin.cpp b/src/plugins/mcusupport/mcusupportplugin.cpp index dec7c66c713..4a81ba2699a 100644 --- a/src/plugins/mcusupport/mcusupportplugin.cpp +++ b/src/plugins/mcusupport/mcusupportplugin.cpp @@ -59,6 +59,7 @@ public: {Constants::RUNCONFIGURATION} }; McuSupportOptionsPage optionsPage; + McuDependenciesKitAspect environmentPathsKitAspect; }; static McuSupportPluginPrivate *dd = nullptr;