diff --git a/src/plugins/mcusupport/mcukitinformation.cpp b/src/plugins/mcusupport/mcukitinformation.cpp index fd8f0892647..0540b231eba 100644 --- a/src/plugins/mcusupport/mcukitinformation.cpp +++ b/src/plugins/mcusupport/mcukitinformation.cpp @@ -24,8 +24,12 @@ ****************************************************************************/ #include "mcukitinformation.h" +#include "mcusupportcmakemapper.h" +#include #include +#include +#include using namespace ProjectExplorer; @@ -57,31 +61,31 @@ McuDependenciesKitAspect::McuDependenciesKitAspect() setPriority(28500); } -Tasks McuDependenciesKitAspect::validate(const Kit *k) const +Tasks McuDependenciesKitAspect::validate(const Kit *kit) const { Tasks result; - QTC_ASSERT(k, return result); + QTC_ASSERT(kit, return result); - const QVariant checkFormat = k->value(McuDependenciesKitAspect::id()); - if (!checkFormat.isNull() && !checkFormat.canConvert(QVariant::List)) + // check dependencies are defined properly for this kit + const QVariant checkFormat = kit->value(McuDependenciesKitAspect::id()); + if (!checkFormat.isValid() || checkFormat.isNull()) + return result; + if (!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)); + // check paths defined in cmake variables for given dependencies exist + const auto cMakeEntries = Utils::NameValueDictionary(configuration(kit)); + for (const auto &dependency: dependencies(kit)) { + auto givenPath = Utils::FilePath::fromString(cMakeEntries.value(dependency.name)); + if (givenPath.isEmpty()) { + result << BuildSystemTask(Task::Warning, tr("CMake variable %1 not defined.").arg( + dependency.name)); } else { - const auto path = Utils::FilePath::fromUserInput(environment.value(dependency.name) - + "/" + dependency.value); - if (!path.exists()) { - result << BuildSystemTask(Task::Warning, - tr("%1 not found.").arg(path.toUserOutput())); + const auto detectionPath = givenPath.resolvePath(dependency.value); + if (!detectionPath.exists()) { + result << BuildSystemTask(Task::Warning, tr("CMake variable %1: path %2 does not exist.").arg( + dependency.name, + detectionPath.toUserOutput())); } } } @@ -89,40 +93,40 @@ Tasks McuDependenciesKitAspect::validate(const Kit *k) const return result; } -void McuDependenciesKitAspect::fix(Kit *k) +void McuDependenciesKitAspect::fix(Kit *kit) { - QTC_ASSERT(k, return ); + QTC_ASSERT(kit, return); - const QVariant variant = k->value(McuDependenciesKitAspect::id()); + const QVariant variant = kit->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()); + qWarning("Kit \"%s\" has a wrong mcu dependencies value set.", qPrintable(kit->displayName())); + setDependencies(kit, Utils::NameValueItems()); } } -KitAspectWidget *McuDependenciesKitAspect::createConfigWidget(Kit *k) const +KitAspectWidget *McuDependenciesKitAspect::createConfigWidget(Kit *kit) const { - QTC_ASSERT(k, return nullptr); - return new McuDependenciesKitAspectWidget(k, this); + QTC_ASSERT(kit, return nullptr); + return new McuDependenciesKitAspectWidget(kit, this); } -KitAspect::ItemList McuDependenciesKitAspect::toUserOutput(const Kit *k) const +KitAspect::ItemList McuDependenciesKitAspect::toUserOutput(const Kit *kit) const { - Q_UNUSED(k) + Q_UNUSED(kit) return {}; } Utils::Id McuDependenciesKitAspect::id() { - return "PE.Profile.McuDependencies"; + return "PE.Profile.McuCMakeDependencies"; } -Utils::NameValueItems McuDependenciesKitAspect::dependencies(const Kit *k) +Utils::NameValueItems McuDependenciesKitAspect::dependencies(const Kit *kit) { - if (k) + if (kit) return Utils::NameValueItem::fromStringList( - k->value(McuDependenciesKitAspect::id()).toStringList()); + kit->value(McuDependenciesKitAspect::id()).toStringList()); return Utils::NameValueItems(); } @@ -133,5 +137,14 @@ void McuDependenciesKitAspect::setDependencies(Kit *k, const Utils::NameValueIte Utils::NameValueItem::toStringList(dependencies)); } +Utils::NameValuePairs McuDependenciesKitAspect::configuration(const Kit *kit) +{ + using namespace CMakeProjectManager; + const auto config = CMakeConfigurationKitAspect::configuration(kit).toList(); + return Utils::transform(config, [](const CMakeConfigItem &it) { + return Utils::NameValuePair(QString::fromUtf8(it.key), QString::fromUtf8(it.value)); + }); +} + } // namespace Internal } // namespace McuSupport diff --git a/src/plugins/mcusupport/mcukitinformation.h b/src/plugins/mcusupport/mcukitinformation.h index 85c811ad668..516efa3af0f 100644 --- a/src/plugins/mcusupport/mcukitinformation.h +++ b/src/plugins/mcusupport/mcukitinformation.h @@ -37,16 +37,17 @@ class McuDependenciesKitAspect final : public ProjectExplorer::KitAspect public: McuDependenciesKitAspect(); - ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const override; - void fix(ProjectExplorer::Kit *k) override; + ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *kit) const override; + void fix(ProjectExplorer::Kit *kit) override; - ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; + ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *kit) const override; - ItemList toUserOutput(const ProjectExplorer::Kit *k) const override; + ItemList toUserOutput(const ProjectExplorer::Kit *kit) const override; static Utils::Id id(); - static Utils::NameValueItems dependencies(const ProjectExplorer::Kit *k); - static void setDependencies(ProjectExplorer::Kit *k, const Utils::NameValueItems &dependencies); + static Utils::NameValueItems dependencies(const ProjectExplorer::Kit *kit); + static void setDependencies(ProjectExplorer::Kit *kit, const Utils::NameValueItems &dependencies); + static Utils::NameValuePairs configuration(const ProjectExplorer::Kit *kit); }; } // namespace Internal diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index a563a3828a3..7cdd292a5c8 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -32,6 +32,7 @@ #include "mcutarget.h" #include "mcusupportplugin.h" #include "mcusupportsdk.h" +#include "mcusupportcmakemapper.h" #include #include @@ -57,6 +58,26 @@ namespace McuKitManager { static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change +static bool expectsCmakeVars(const McuTarget *mcuTarget) +{ + return mcuTarget->qulVersion() >= QVersionNumber{2, 0}; +} + +void remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems) +{ + const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems); + const auto cmakeVarNames = Utils::transform(cmakeVars, &CMakeConfigItem::key); + + // First filter out all Qul2.x CMake vars + auto config = Utils::filtered(CMakeConfigurationKitAspect::configuration(kit), + [&](const auto &configItem) { + return !cmakeVarNames.contains(configItem.key); + }); + // Then append them with new values + config.append(cmakeVars); + CMakeConfigurationKitAspect::setConfiguration(kit, config); +} + static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) { switch (tcPackage->toolchainType()) { @@ -85,7 +106,6 @@ static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) } } - static void setKitProperties(const QString &kitName, Kit *k, const McuTarget *mcuTarget, @@ -120,6 +140,67 @@ static void setKitProperties(const QString &kitName, } +static void setKitEnvironment(Kit *k, + const McuTarget *mcuTarget, + const McuAbstractPackage *qtForMCUsSdkPackage) +{ + EnvironmentItems changes; + QStringList pathAdditions; + + // The Desktop version depends on the Qt shared libs in Qul_DIR/bin. + // If CMake's fileApi is avaialble, we can rely on the "Add library search path to PATH" + // feature of the run configuration. Otherwise, we just prepend the path, here. + if (mcuTarget->toolChainPackage()->isDesktopToolchain() + && !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi()) + pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput()); + + auto processPackage = [&pathAdditions, &changes](const McuAbstractPackage *package) { + if (package->isAddToSystemPath()) + pathAdditions.append(package->path().toUserOutput()); + if (!package->environmentVariableName().isEmpty()) + changes.append({package->environmentVariableName(), package->path().toUserOutput()}); + }; + for (auto package : mcuTarget->packages()) + processPackage(package); + processPackage(qtForMCUsSdkPackage); + + if (McuSupportOptions::kitsNeedQtVersion()) + changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"}); + + // Hack, this problem should be solved in lower layer + if (expectsCmakeVars(mcuTarget)) { + remapQul2xCmakeVars(k, changes); + } + + EnvironmentKitAspect::setEnvironmentChanges(k, changes); +} + +void updateKitEnvironment(Kit *k, const McuTarget *mcuTarget) +{ + EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k); + for (auto package : mcuTarget->packages()) { + const QString varName = package->environmentVariableName(); + if (!varName.isEmpty() && package->isValidStatus()) { + const int index = Utils::indexOf(changes, [varName](const EnvironmentItem &item) { + return item.name == varName; + }); + const EnvironmentItem item = {package->environmentVariableName(), + package->path().toUserOutput()}; + if (index != -1) + changes.replace(index, item); + else + changes.append(item); + } + } + + // Hack, this problem should be solved in lower layer + if (expectsCmakeVars(mcuTarget)) { + remapQul2xCmakeVars(k, changes); + } + + EnvironmentKitAspect::setEnvironmentChanges(k, changes); +} + static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage) { if (tcPackage->isDesktopToolchain()) { @@ -166,8 +247,9 @@ static void setKitDependencies(Kit *k, NameValueItems dependencies; auto processPackage = [&dependencies](const McuAbstractPackage *package) { - if (!package->environmentVariableName().isEmpty()) - dependencies.append({package->environmentVariableName(), + const auto cmakeVariableName = mapEnvVarToQul2xCmakeVar(package->environmentVariableName()); + if (!cmakeVariableName.isEmpty()) + dependencies.append({cmakeVariableName, package->detectionPath().toUserOutput()}); }; for (auto package : mcuTarget->packages()) @@ -298,12 +380,12 @@ QList upgradeableKits(const McuTarget *mcuTarget, QList kitsWithMismatchedDependencies(const McuTarget *mcuTarget) { return Utils::filtered(existingKits(mcuTarget), [mcuTarget](Kit *kit) { - const auto environment = Utils::NameValueDictionary( - Utils::NameValueItem::toStringList(EnvironmentKitAspect::environmentChanges(kit))); + const auto entries = Utils::NameValueDictionary(McuDependenciesKitAspect::configuration(kit)); return Utils::anyOf(mcuTarget->packages(), - [&environment](const McuAbstractPackage *package) { - return !package->environmentVariableName().isEmpty() - && environment.value(package->environmentVariableName()) + [&entries](const McuAbstractPackage *package) { + const QString cmakeVariableName = mapEnvVarToQul2xCmakeVar(package->environmentVariableName()); + return !cmakeVariableName.isEmpty() + && entries.value(cmakeVariableName) != package->path().toUserOutput(); }); }); @@ -332,7 +414,7 @@ Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk) setKitDevice(k, mcuTarget); setKitToolchains(k, mcuTarget->toolChainPackage()); setKitDebugger(k, mcuTarget->toolChainPackage()); - McuSupportOptions::setKitEnvironment(k, mcuTarget, qtForMCUsSdk); + setKitEnvironment(k, mcuTarget, qtForMCUsSdk); setKitDependencies(k, mcuTarget, qtForMCUsSdk); setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk->path()); setKitQtVersionOptions(k); @@ -479,7 +561,7 @@ void upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuAbstractPackage *qtForMCUsSdk) { setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path()); - McuSupportOptions::setKitEnvironment(kit, mcuTarget, qtForMCUsSdk); + setKitEnvironment(kit, mcuTarget, qtForMCUsSdk); setKitDependencies(kit, mcuTarget, qtForMCUsSdk); } @@ -493,7 +575,8 @@ void fixKitsDependencies() for (const auto &target : qAsConst(repo.mcuTargets)) { if (target->isValid()) { for (auto *kit : kitsWithMismatchedDependencies(target)) { - McuSupportOptions::updateKitEnvironment(kit, target); + // ToDo: should not be environment, but cmake vars + updateKitEnvironment(kit, target); } } } diff --git a/src/plugins/mcusupport/mcukitmanager.h b/src/plugins/mcusupport/mcukitmanager.h index 1814fb26432..3c6df9824a6 100644 --- a/src/plugins/mcusupport/mcukitmanager.h +++ b/src/plugins/mcusupport/mcukitmanager.h @@ -71,6 +71,7 @@ namespace McuKitManager // Fixing kits: void fixKitsDependencies(); void fixExistingKits(); + void updateKitEnvironment(ProjectExplorer::Kit *k, const McuTarget *mcuTarget); // Outdated kits: QList outdatedKits(); diff --git a/src/plugins/mcusupport/mcusupportcmakemapper.cpp b/src/plugins/mcusupport/mcusupportcmakemapper.cpp index 7f69f4f6716..ddd0b758612 100644 --- a/src/plugins/mcusupport/mcusupportcmakemapper.cpp +++ b/src/plugins/mcusupport/mcusupportcmakemapper.cpp @@ -58,6 +58,7 @@ static const QHash &envVarToCMakeVarMapping() {"JLINK_PATH", "JLINK_PATH"}, {"CYPRESS_AUTO_FLASH_UTILITY_DIR", "INFINEON_AUTO_FLASH_UTILITY_DIR"}, {"EK_RA6M3G_E2_PROJECT_PATH", "EK_RA6M3G_E2_PROJECT_PATH"}, + {"Qul_DIR", "Qul_ROOT"}, }; return mapping; } @@ -77,3 +78,8 @@ QList McuSupport::Internal::mapEnvVarsToQu return !item.key.isEmpty(); }); } + +QString McuSupport::Internal::mapEnvVarToQul2xCmakeVar(const QString &envVar) +{ + return envVarToCMakeVarMapping().value(envVar, QString()); +} diff --git a/src/plugins/mcusupport/mcusupportcmakemapper.h b/src/plugins/mcusupport/mcusupportcmakemapper.h index f5da2092def..2f001bbdd68 100644 --- a/src/plugins/mcusupport/mcusupportcmakemapper.h +++ b/src/plugins/mcusupport/mcusupportcmakemapper.h @@ -31,5 +31,6 @@ namespace McuSupport { namespace Internal { QList mapEnvVarsToQul2xCmakeVars( const Utils::EnvironmentItems &envVars); +QString mapEnvVarToQul2xCmakeVar(const QString &envVar); } } // namespace McuSupport diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index 47475fb8161..aedfb74440a 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -29,7 +29,6 @@ #include "mcutarget.h" #include "mcukitmanager.h" #include "mcukitinformation.h" -#include "mcusupportcmakemapper.h" #include "mcusupportconstants.h" #include "mcusupportsdk.h" #include "mcusupportplugin.h" @@ -149,87 +148,6 @@ FilePath McuSupportOptions::qulDirFromSettings() {}); } -void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems) -{ - const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems); - const auto cmakeVarNames = Utils::transform(cmakeVars, &CMakeConfigItem::key); - - // First filter out all Qul2.x CMake vars - auto config = Utils::filtered(CMakeConfigurationKitAspect::configuration(kit), - [&](const auto &configItem) { - return !cmakeVarNames.contains(configItem.key); - }); - // Then append them with new values - config.append(cmakeVars); - CMakeConfigurationKitAspect::setConfiguration(kit, config); -} - -static bool expectsCmakeVars(const McuTarget *mcuTarget) -{ - return mcuTarget->qulVersion() >= QVersionNumber{2, 0}; -} - -void McuSupportOptions::setKitEnvironment(Kit *k, - const McuTarget *mcuTarget, - const McuAbstractPackage *qtForMCUsSdkPackage) -{ - EnvironmentItems changes; - QStringList pathAdditions; - - // The Desktop version depends on the Qt shared libs in Qul_DIR/bin. - // If CMake's fileApi is avaialble, we can rely on the "Add library search path to PATH" - // feature of the run configuration. Otherwise, we just prepend the path, here. - if (mcuTarget->toolChainPackage()->isDesktopToolchain() - && !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi()) - pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput()); - - auto processPackage = [&pathAdditions, &changes](const McuAbstractPackage *package) { - if (package->isAddToSystemPath()) - pathAdditions.append(package->path().toUserOutput()); - if (!package->environmentVariableName().isEmpty()) - changes.append({package->environmentVariableName(), package->path().toUserOutput()}); - }; - for (auto package : mcuTarget->packages()) - processPackage(package); - processPackage(qtForMCUsSdkPackage); - - if (McuSupportOptions::kitsNeedQtVersion()) - changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"}); - - // Hack, this problem should be solved in lower layer - if (expectsCmakeVars(mcuTarget)) { - McuSupportOptions::remapQul2xCmakeVars(k, changes); - } - - EnvironmentKitAspect::setEnvironmentChanges(k, changes); -} - -void McuSupportOptions::updateKitEnvironment(Kit *k, const McuTarget *mcuTarget) -{ - EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k); - for (auto package : mcuTarget->packages()) { - const QString varName = package->environmentVariableName(); - if (!varName.isEmpty() && package->isValidStatus()) { - const int index = Utils::indexOf(changes, [varName](const EnvironmentItem &item) { - return item.name == varName; - }); - const EnvironmentItem item = {package->environmentVariableName(), - package->path().toUserOutput()}; - if (index != -1) - changes.replace(index, item); - else - changes.append(item); - } - } - - // Hack, this problem should be solved in lower layer - if (expectsCmakeVars(mcuTarget)) { - remapQul2xCmakeVars(k, changes); - } - - EnvironmentKitAspect::setEnvironmentChanges(k, changes); -} - McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades() { QMessageBox upgradePopup(Core::ICore::dialogParent()); diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 04dbb24b6ae..144462a064d 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -74,11 +74,6 @@ public: McuSdkRepository sdkRepository; void setQulDir(const Utils::FilePath &dir); - static void setKitEnvironment(ProjectExplorer::Kit *, - const McuTarget *, - const McuAbstractPackage *); - static void updateKitEnvironment(ProjectExplorer::Kit *, const McuTarget *); - static void remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &); static Utils::FilePath qulDirFromSettings(); static McuKitManager::UpgradeOption askForKitUpgrades(); diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 62b8fd9c278..f2a7dfddc4b 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -82,7 +82,7 @@ void McuSupportTest::test_addNewKit() void McuSupportTest::test_addFreeRtosCmakeVarToKit() { - McuSupportOptions::updateKitEnvironment(&kit, &mcuTarget); + McuKitManager::updateKitEnvironment(&kit, &mcuTarget); QVERIFY(kit.hasValue(EnvironmentKitAspect::id())); QVERIFY(kit.isValid());