McuSupport: remove cmake mapper

Starting with Qt For MCUs 2.0, environment variables are not
used to track dependencies any more, but cmake variables are.
Due to time constraints, we implemented a env-to-cmake mapper
to cover that gap at the moment. This patch removes that hack
and implements tracking dependencies through cmake variables.

Task-number: QTCREATORBUG-26904
Change-Id: Id8553a764d212d9b12e4adc54fc56233bfeb9a5b
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Christiaan Janssen
2022-02-22 13:36:55 +01:00
committed by Piotr Mućko
parent cd8c4ced81
commit e293aab725
17 changed files with 487 additions and 545 deletions

View File

@@ -17,7 +17,6 @@ add_qtc_plugin(McuSupport
mcusupportsdk.cpp mcusupportsdk.h mcusupportsdk.cpp mcusupportsdk.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h
mcusupportversiondetection.cpp mcusupportversiondetection.h mcusupportversiondetection.cpp mcusupportversiondetection.h
mcusupportcmakemapper.cpp mcusupportcmakemapper.h
mcutargetdescription.h mcutargetdescription.h
) )

View File

@@ -46,6 +46,7 @@ public:
}; };
virtual QString label() const = 0; virtual QString label() const = 0;
virtual const QString &cmakeVariableName() const = 0;
virtual const QString &environmentVariableName() const = 0; virtual const QString &environmentVariableName() const = 0;
virtual bool isAddToSystemPath() const = 0; virtual bool isAddToSystemPath() const = 0;
virtual void setVersions(const QStringList &) = 0; virtual void setVersions(const QStringList &) = 0;

View File

@@ -24,7 +24,6 @@
****************************************************************************/ ****************************************************************************/
#include "mcukitinformation.h" #include "mcukitinformation.h"
#include "mcusupportcmakemapper.h"
#include <cmakeprojectmanager/cmakekitinformation.h> #include <cmakeprojectmanager/cmakekitinformation.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>

View File

@@ -26,13 +26,12 @@
#include "mcukitmanager.h" #include "mcukitmanager.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportconstants.h"
#include "mcukitinformation.h" #include "mcukitinformation.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcutarget.h" #include "mcusupportconstants.h"
#include "mcusupportplugin.h" #include "mcusupportplugin.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcusupportcmakemapper.h" #include "mcutarget.h"
#include <cmakeprojectmanager/cmakekitinformation.h> #include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketoolmanager.h> #include <cmakeprojectmanager/cmaketoolmanager.h>
@@ -47,39 +46,43 @@
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
using CMakeProjectManager::CMakeConfig;
using CMakeProjectManager::CMakeConfigItem; using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect; using CMakeProjectManager::CMakeConfigurationKitAspect;
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace McuSupport { namespace McuSupport::Internal {
namespace Internal {
// Utils for managing CMake Configurations
static QMap<QByteArray, QByteArray> cMakeConfigToMap(const CMakeConfig &config)
{
QMap<QByteArray, QByteArray> map;
for (const auto &configItem : qAsConst(config.toList())) {
map.insert(configItem.key, configItem.value);
}
return map;
}
static CMakeConfig mapToCMakeConfig(const QMap<QByteArray, QByteArray> &map)
{
QList<CMakeConfigItem> asList;
for (auto it = map.constKeyValueBegin(); it != map.constKeyValueEnd(); ++it) {
asList.append(CMakeConfigItem(it->first, it->second));
}
return CMakeConfig(asList);
}
namespace McuKitManager { namespace McuKitManager {
static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change
static bool expectsCmakeVars(const McuTarget *mcuTarget) class McuKitFactory
{
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)
{ {
public:
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{
switch (tcPackage->toolchainType()) { switch (tcPackage->toolchainType()) {
case McuToolChainPackage::ToolChainType::Unsupported: case McuToolChainPackage::ToolChainType::Unsupported:
return; return;
@@ -104,13 +107,13 @@ static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
static void setKitProperties(const QString &kitName, static void setKitProperties(const QString &kitName,
Kit *k, Kit *k,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const FilePath &sdkPath) const FilePath &sdkPath)
{ {
using namespace Constants; using namespace Constants;
k->setUnexpandedDisplayName(kitName); k->setUnexpandedDisplayName(kitName);
@@ -126,7 +129,8 @@ static void setKitProperties(const QString &kitName,
if (mcuTarget->toolChainPackage()->isDesktopToolchain()) if (mcuTarget->toolChainPackage()->isDesktopToolchain())
k->setDeviceTypeForIcon(DEVICE_TYPE); k->setDeviceTypeForIcon(DEVICE_TYPE);
k->setValue(QtSupport::SuppliesQtQuickImportPath::id(), true); k->setValue(QtSupport::SuppliesQtQuickImportPath::id(), true);
k->setValue(QtSupport::KitQmlImportPath::id(), sdkPath.pathAppended("include/qul").toVariant()); k->setValue(QtSupport::KitQmlImportPath::id(),
sdkPath.pathAppended("include/qul").toVariant());
k->setValue(QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(), true); k->setValue(QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(), true);
QSet<Id> irrelevant = { QSet<Id> irrelevant = {
SysRootKitAspect::id(), SysRootKitAspect::id(),
@@ -137,72 +141,10 @@ static void setKitProperties(const QString &kitName,
if (!McuSupportOptions::kitsNeedQtVersion()) if (!McuSupportOptions::kitsNeedQtVersion())
irrelevant.insert(QtSupport::QtKitAspect::id()); irrelevant.insert(QtSupport::QtKitAspect::id());
k->setIrrelevantAspects(irrelevant); k->setIrrelevantAspects(irrelevant);
}
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); static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
} {
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()) { 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
return; return;
@@ -229,28 +171,27 @@ static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
static void setKitDevice(Kit *k, const McuTarget *mcuTarget) static void setKitDevice(Kit *k, const McuTarget *mcuTarget)
{ {
// "Device Type" Desktop is the default. We use that for the Qt for MCUs Desktop Kit // "Device Type" Desktop is the default. We use that for the Qt for MCUs Desktop Kit
if (mcuTarget->toolChainPackage()->isDesktopToolchain()) if (mcuTarget->toolChainPackage()->isDesktopToolchain())
return; return;
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE); DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
} }
static void setKitDependencies(Kit *k, static void setKitDependencies(Kit *k,
const McuTarget *mcuTarget, const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage) const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
NameValueItems dependencies; NameValueItems dependencies;
auto processPackage = [&dependencies](const McuAbstractPackage *package) { auto processPackage = [&dependencies](const McuAbstractPackage *package) {
const auto cmakeVariableName = mapEnvVarToQul2xCmakeVar(package->environmentVariableName()); const auto cmakeVariableName = package->cmakeVariableName();
if (!cmakeVariableName.isEmpty()) if (!cmakeVariableName.isEmpty())
dependencies.append({cmakeVariableName, dependencies.append({cmakeVariableName, package->detectionPath().toUserOutput()});
package->detectionPath().toUserOutput()});
}; };
for (auto package : mcuTarget->packages()) for (auto package : mcuTarget->packages())
processPackage(package); processPackage(package);
@@ -261,70 +202,151 @@ static void setKitDependencies(Kit *k,
auto irrelevant = k->irrelevantAspects(); auto irrelevant = k->irrelevantAspects();
irrelevant.insert(McuDependenciesKitAspect::id()); irrelevant.insert(McuDependenciesKitAspect::id());
k->setIrrelevantAspects(irrelevant); k->setIrrelevantAspects(irrelevant);
} }
static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePath &qulDir) static void setKitEnvironment(Kit *k,
{ const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
EnvironmentItems changes;
QStringList pathAdditions; // clazy:exclude=inefficient-qlist-soft
// 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](const McuAbstractPackage *package) {
if (package->isAddToSystemPath())
pathAdditions.append(package->path().toUserOutput());
};
for (auto package : mcuTarget->packages())
processPackage(package);
processPackage(qtForMCUsSdkPackage);
if (!pathAdditions.isEmpty()) {
const QString path = QLatin1String(HostOsInfo::isWindowsHost() ? "Path" : "PATH");
pathAdditions.append("${" + path + "}");
changes.append({path, pathAdditions.join(HostOsInfo::pathListSeparator())});
}
if (McuSupportOptions::kitsNeedQtVersion())
changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"});
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
static void setKitCMakeOptions(Kit *k,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
using namespace CMakeProjectManager; using namespace CMakeProjectManager;
auto configMap = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(k));
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously // CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
if (mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHS if (mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHS
&& mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHSArm) { && mcuTarget->toolChainPackage()->toolchainType()
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}")); != McuToolChainPackage::ToolChainType::GHSArm) {
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}")); configMap.insert("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}");
configMap.insert("CMAKE_C_COMPILER", "%{Compiler:Executable:C}");
} }
if (!mcuTarget->toolChainPackage()->isDesktopToolchain()) { if (!mcuTarget->toolChainPackage()->isDesktopToolchain()) {
const FilePath cMakeToolchainFile = qulDir.pathAppended( const FilePath cMakeToolchainFile = qtForMCUsSdkPackage->path().pathAppended(
"lib/cmake/Qul/toolchain/" + mcuTarget->toolChainPackage()->cmakeToolChainFileName()); "lib/cmake/Qul/toolchain/"
+ mcuTarget->toolChainPackage()->cmakeToolChainFileName());
config.append( configMap.insert("CMAKE_TOOLCHAIN_FILE", cMakeToolchainFile.toString().toUtf8());
CMakeConfigItem("CMAKE_TOOLCHAIN_FILE", cMakeToolchainFile.toString().toUtf8()));
if (!cMakeToolchainFile.exists()) { if (!cMakeToolchainFile.exists()) {
printMessage(McuTarget::tr( printMessage(
McuTarget::tr(
"Warning for target %1: missing CMake toolchain file expected at %2.") "Warning for target %1: missing CMake toolchain file expected at %2.")
.arg(kitName(mcuTarget), .arg(generateKitNameFromTarget(mcuTarget),
cMakeToolchainFile.toUserOutput()), cMakeToolchainFile.toUserOutput()),
false); false);
} }
} }
const FilePath generatorsPath = qulDir.pathAppended("/lib/cmake/Qul/QulGenerators.cmake"); const FilePath generatorsPath = qtForMCUsSdkPackage->path().pathAppended(
config.append(CMakeConfigItem("QUL_GENERATORS", generatorsPath.toString().toUtf8())); "/lib/cmake/Qul/QulGenerators.cmake");
configMap.insert("QUL_GENERATORS", generatorsPath.toString().toUtf8());
if (!generatorsPath.exists()) { if (!generatorsPath.exists()) {
printMessage(McuTarget::tr("Warning for target %1: missing QulGenerators expected at %2.") printMessage(McuTarget::tr(
.arg(kitName(mcuTarget), generatorsPath.toUserOutput()), "Warning for target %1: missing QulGenerators expected at %2.")
.arg(generateKitNameFromTarget(mcuTarget),
generatorsPath.toUserOutput()),
false); false);
} }
config.append(CMakeConfigItem("QUL_PLATFORM", mcuTarget->platform().name.toUtf8())); configMap.insert("QUL_PLATFORM", mcuTarget->platform().name.toUtf8());
if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth) if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH", configMap.insert("QUL_COLOR_DEPTH", QString::number(mcuTarget->colorDepth()).toLatin1());
QString::number(mcuTarget->colorDepth()).toLatin1()));
if (McuSupportOptions::kitsNeedQtVersion()) if (McuSupportOptions::kitsNeedQtVersion())
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}")); configMap.insert("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}");
CMakeConfigurationKitAspect::setConfiguration(k, config);
if (HostOsInfo::isWindowsHost()) { if (HostOsInfo::isWindowsHost()) {
auto type = mcuTarget->toolChainPackage()->toolchainType(); auto type = mcuTarget->toolChainPackage()->toolchainType();
if (type == McuToolChainPackage::ToolChainType::GHS || type == McuToolChainPackage::ToolChainType::GHSArm) { if (type == McuToolChainPackage::ToolChainType::GHS
|| type == McuToolChainPackage::ToolChainType::GHSArm) {
// See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802 // See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802
// and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803 // and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM"); CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
} }
} }
}
static void setKitQtVersionOptions(Kit *k) auto processPackage = [&configMap](const McuAbstractPackage *package) {
{ if (!package->cmakeVariableName().isEmpty())
configMap.insert(package->cmakeVariableName().toUtf8(),
package->path().toUserOutput().toUtf8());
};
for (auto package : mcuTarget->packages())
processPackage(package);
processPackage(qtForMCUsSdkPackage);
CMakeConfigurationKitAspect::setConfiguration(k, mapToCMakeConfig(configMap));
}
static void setKitQtVersionOptions(Kit *k)
{
if (!McuSupportOptions::kitsNeedQtVersion()) if (!McuSupportOptions::kitsNeedQtVersion())
QtSupport::QtKitAspect::setQtVersion(k, nullptr); QtSupport::QtKitAspect::setQtVersion(k, nullptr);
// else: auto-select a Qt version // else: auto-select a Qt version
}
}; // class McuKitFactory
// Construct kit
Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
{
const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) {
KitGuard kitGuard(k);
McuKitFactory::setKitProperties(generateKitNameFromTarget(mcuTarget),
k,
mcuTarget,
qtForMCUsSdk->path());
McuKitFactory::setKitDevice(k, mcuTarget);
McuKitFactory::setKitToolchains(k, mcuTarget->toolChainPackage());
McuKitFactory::setKitDebugger(k, mcuTarget->toolChainPackage());
McuKitFactory::setKitEnvironment(k, mcuTarget, qtForMCUsSdk);
McuKitFactory::setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk);
McuKitFactory::setKitDependencies(k, mcuTarget, qtForMCUsSdk);
McuKitFactory::setKitQtVersionOptions(k);
k->setup();
k->fix();
};
return KitManager::registerKit(init);
} }
QString kitName(const McuTarget *mcuTarget) // Kit Information
QString generateKitNameFromTarget(const McuTarget *mcuTarget)
{ {
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage(); const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain() const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
@@ -345,6 +367,36 @@ QString kitName(const McuTarget *mcuTarget)
compilerName); compilerName);
} }
// Kit Information
QVersionNumber kitQulVersion(const Kit *kit)
{
return QVersionNumber::fromString(
kit->value(McuSupport::Constants::KIT_MCUTARGET_SDKVERSION_KEY).toString());
}
// Kit Information
static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
{
const auto config = CMakeConfigurationKitAspect::configuration(kit).toList();
const auto keyName = variableName.toUtf8();
for (const CMakeConfigItem &configItem : config) {
if (configItem.key == keyName)
return FilePath::fromUserInput(QString::fromUtf8(configItem.value));
}
return FilePath();
}
// Kit Information
bool kitIsUpToDate(const Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return kitQulVersion(kit) == mcuTarget->qulVersion()
&& kitDependencyPath(kit, qtForMCUsSdkPackage->cmakeVariableName()).toUserOutput()
== qtForMCUsSdkPackage->path().toUserOutput();
}
// Queries
QList<Kit *> existingKits(const McuTarget *mcuTarget) QList<Kit *> existingKits(const McuTarget *mcuTarget)
{ {
using namespace Constants; using namespace Constants;
@@ -361,14 +413,15 @@ QList<Kit *> existingKits(const McuTarget *mcuTarget)
}); });
} }
QList<Kit *> matchingKits(const McuTarget *mcuTarget, // Queries
const McuAbstractPackage *qtForMCUsSdkPackage) QList<Kit *> matchingKits(const McuTarget *mcuTarget, 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);
}); });
} }
// Queries
QList<Kit *> upgradeableKits(const McuTarget *mcuTarget, QList<Kit *> upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage) const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
@@ -377,20 +430,21 @@ QList<Kit *> upgradeableKits(const McuTarget *mcuTarget,
}); });
} }
// 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(McuDependenciesKitAspect::configuration(kit)); const auto entries = Utils::NameValueDictionary(
return Utils::anyOf(mcuTarget->packages(), McuDependenciesKitAspect::configuration(kit));
[&entries](const McuAbstractPackage *package) { return Utils::anyOf(mcuTarget->packages(), [&entries](const McuAbstractPackage *package) {
const QString cmakeVariableName = mapEnvVarToQul2xCmakeVar(package->environmentVariableName()); const QString cmakeVariableName = package->cmakeVariableName();
return !cmakeVariableName.isEmpty() return !cmakeVariableName.isEmpty()
&& entries.value(cmakeVariableName) && entries.value(cmakeVariableName) != package->path().toUserOutput();
!= package->path().toUserOutput();
}); });
}); });
} }
// Queries
QList<Kit *> outdatedKits() QList<Kit *> outdatedKits()
{ {
return Utils::filtered(KitManager::kits(), [](Kit *kit) { return Utils::filtered(KitManager::kits(), [](Kit *kit) {
@@ -399,57 +453,7 @@ QList<Kit *> outdatedKits()
}); });
} }
void removeOutdatedKits() // Maintenance
{
for (auto kit : outdatedKits())
KitManager::deregisterKit(kit);
}
Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
{
const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) {
KitGuard kitGuard(k);
setKitProperties(kitName(mcuTarget), k, mcuTarget, qtForMCUsSdk->path());
setKitDevice(k, mcuTarget);
setKitToolchains(k, mcuTarget->toolChainPackage());
setKitDebugger(k, mcuTarget->toolChainPackage());
setKitEnvironment(k, mcuTarget, qtForMCUsSdk);
setKitDependencies(k, mcuTarget, qtForMCUsSdk);
setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk->path());
setKitQtVersionOptions(k);
k->setup();
k->fix();
};
return KitManager::registerKit(init);
}
QVersionNumber kitQulVersion(const Kit *kit)
{
return QVersionNumber::fromString(
kit->value(McuSupport::Constants::KIT_MCUTARGET_SDKVERSION_KEY).toString());
}
static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
{
for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) {
if (nameValueItem.name == variableName)
return FilePath::fromUserInput(nameValueItem.value);
}
return FilePath();
}
bool kitIsUpToDate(const Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return kitQulVersion(kit) == mcuTarget->qulVersion()
&& kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()).toUserOutput()
== qtForMCUsSdkPackage->path().toUserOutput();
}
void createAutomaticKits() void createAutomaticKits()
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
@@ -467,14 +471,16 @@ void createAutomaticKits()
break; break;
} }
case McuAbstractPackage::Status::InvalidPath: { case McuAbstractPackage::Status::InvalidPath: {
printMessage(McuPackage::tr("Path %1 does not exist. Add the path in Tools > Options > " printMessage(McuPackage::tr(
"Path %1 does not exist. Add the path in Tools > Options > "
"Devices > MCU.") "Devices > MCU.")
.arg(qtForMCUsPackage->path().toUserOutput()), .arg(qtForMCUsPackage->path().toUserOutput()),
true); true);
break; break;
} }
case McuAbstractPackage::Status::EmptyPath: { case McuAbstractPackage::Status::EmptyPath: {
printMessage(McuPackage::tr("Missing %1. Add the path in Tools > Options > Devices > MCU.") printMessage(McuPackage::tr(
"Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath().toUserOutput()), .arg(qtForMCUsPackage->detectionPath().toUserOutput()),
true); true);
return; return;
@@ -486,7 +492,9 @@ void createAutomaticKits()
} }
if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) { if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) {
printMessage(McuPackage::tr("No CMake tool was detected. Add a CMake tool in Tools > Options > " printMessage(
McuPackage::tr(
"No CMake tool was detected. Add a CMake tool in Tools > Options > "
"Kits > CMake."), "Kits > CMake."),
true); true);
return; return;
@@ -523,6 +531,11 @@ void createAutomaticKits()
delete qtForMCUsPackage; delete qtForMCUsPackage;
} }
// Maintenance
// when the SDK version has changed, and the user has given permission
// to upgrade, create new kits with current data, for the targets
// for which kits already existed
// function parameter is option to keep the old ones or delete them
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption) void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
{ {
if (upgradeOption == UpgradeOption::Ignore) if (upgradeOption == UpgradeOption::Ignore)
@@ -556,16 +569,26 @@ void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
delete qtForMCUsPackage; delete qtForMCUsPackage;
} }
// Maintenance
// when the user manually asks to upgrade a specific kit
// 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 McuAbstractPackage *qtForMCUsSdk)
{ {
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path()); McuKitFactory::setKitProperties(generateKitNameFromTarget(mcuTarget),
setKitEnvironment(kit, mcuTarget, qtForMCUsSdk); kit,
setKitDependencies(kit, mcuTarget, qtForMCUsSdk); mcuTarget,
qtForMCUsSdk->path());
McuKitFactory::setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
McuKitFactory::setKitCMakeOptions(kit, mcuTarget, qtForMCUsSdk);
McuKitFactory::setKitDependencies(kit, mcuTarget, qtForMCUsSdk);
} }
void fixKitsDependencies() // Maintenance
// If the user changed a path in the McuSupport plugin's UI
// update the corresponding cmake variables in all existing kits
void updatePathsInExistingKits()
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
@@ -575,8 +598,23 @@ void fixKitsDependencies()
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)) {
// ToDo: should not be environment, but cmake vars auto changes = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(kit));
updateKitEnvironment(kit, target);
const auto updateForPackage = [&changes](const McuAbstractPackage *package) {
if (!package->cmakeVariableName().isEmpty() && package->isValidStatus()) {
changes.insert(package->cmakeVariableName().toUtf8(),
package->path().toUserOutput().toUtf8());
}
};
for (auto package : target->packages()) {
updateForPackage(package);
}
updateForPackage(qtForMCUsPackage);
CMakeConfigurationKitAspect::setConfiguration(kit,
CMakeProjectManager::CMakeConfig(
mapToCMakeConfig(changes)));
} }
} }
} }
@@ -585,9 +623,9 @@ void fixKitsDependencies()
delete qtForMCUsPackage; delete qtForMCUsPackage;
} }
/** // Maintenance
* @brief Fix/update existing kits if needed // if we changed minor details in the kits across versions of QtCreator
*/ // this function updates those details in existing older kits
void fixExistingKits() void fixExistingKits()
{ {
for (Kit *kit : KitManager::kits()) { for (Kit *kit : KitManager::kits()) {
@@ -650,7 +688,8 @@ void fixExistingKits()
for (const auto &target : qAsConst(repo.mcuTargets)) for (const auto &target : qAsConst(repo.mcuTargets))
for (auto kit : existingKits(target)) { for (auto kit : existingKits(target)) {
if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) { if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) {
setKitDependencies(kit, target, qtForMCUsPackage); McuKitFactory::setKitCMakeOptions(kit, target, qtForMCUsPackage);
McuKitFactory::setKitDependencies(kit, target, qtForMCUsPackage);
} }
} }
@@ -659,6 +698,13 @@ void fixExistingKits()
delete qtForMCUsPackage; delete qtForMCUsPackage;
} }
// Maintenance
// removes kits with older schemes
void removeOutdatedKits()
{
for (auto kit : outdatedKits())
KitManager::deregisterKit(kit);
}
} // namespace McuKitManager } // namespace McuKitManager
} // namespace Internal } // namespace McuSupport::Internal
} // namespace McuSupport

View File

@@ -25,8 +25,8 @@
#pragma once #pragma once
#include <utils/environmentfwd.h>
#include "mcusupport_global.h" #include "mcusupport_global.h"
#include <utils/environmentfwd.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QObject> #include <QObject>
@@ -44,43 +44,41 @@ class McuAbstractPackage;
class McuToolChainPackage; class McuToolChainPackage;
class McuTarget; class McuTarget;
namespace McuKitManager namespace McuKitManager {
{ enum class UpgradeOption { Ignore, Keep, Replace };
enum class UpgradeOption {
Ignore,
Keep,
Replace
};
// Creating kits: // Kit Factory
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk); ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
void createAutomaticKits();
// Querying the kits: // Kit information
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget); QString generateKitNameFromTarget(const McuTarget *mcuTarget);
QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget, QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
bool kitIsUpToDate(const ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage); const McuAbstractPackage *qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> upgradeableKits(
const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
// Upgrading kits: // Queries
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption); QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
void upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk); QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
QList<ProjectExplorer::Kit *> outdatedKits();
// Fixing kits: // Maintenance
void fixKitsDependencies(); void createAutomaticKits();
void fixExistingKits(); void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption);
void updateKitEnvironment(ProjectExplorer::Kit *k, const McuTarget *mcuTarget); void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk);
// Outdated kits: // Fixing kits:
QList<ProjectExplorer::Kit *> outdatedKits(); void updatePathsInExistingKits();
void removeOutdatedKits(); void fixExistingKits();
// Querying kits: // Outdated kits:
QString kitName(const McuTarget* mcuTarget); void removeOutdatedKits();
QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
bool kitIsUpToDate(const ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
} // namespace McuKitManager } // namespace McuKitManager
} // namespace Internal } // namespace Internal

View File

@@ -53,6 +53,7 @@ McuPackage::McuPackage(const QString &label,
const FilePath &defaultPath, const FilePath &defaultPath,
const FilePath &detectionPath, const FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
const QString &cmakeVarName,
const QString &envVarName, const QString &envVarName,
const QString &downloadUrl, const QString &downloadUrl,
const McuPackageVersionDetector *versionDetector, const McuPackageVersionDetector *versionDetector,
@@ -64,6 +65,7 @@ McuPackage::McuPackage(const QString &label,
, m_settingsKey(settingsKey) , m_settingsKey(settingsKey)
, m_versionDetector(versionDetector) , m_versionDetector(versionDetector)
, m_relativePathModifier(relativePathModifier) , m_relativePathModifier(relativePathModifier)
, m_cmakeVariableName(cmakeVarName)
, m_environmentVariableName(envVarName) , m_environmentVariableName(envVarName)
, m_downloadUrl(downloadUrl) , m_downloadUrl(downloadUrl)
, m_addToSystemPath(addToSystemPath) , m_addToSystemPath(addToSystemPath)
@@ -81,6 +83,11 @@ QString McuPackage::settingsKey() const
return m_settingsKey; return m_settingsKey;
} }
const QString &McuPackage::cmakeVariableName() const
{
return m_cmakeVariableName;
}
const QString &McuPackage::environmentVariableName() const const QString &McuPackage::environmentVariableName() const
{ {
return m_environmentVariableName; return m_environmentVariableName;
@@ -278,9 +285,10 @@ McuToolChainPackage::McuToolChainPackage(const QString &label,
const FilePath &detectionPath, const FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
McuToolChainPackage::ToolChainType type, McuToolChainPackage::ToolChainType type,
const QString &cmakeVarName,
const QString &envVarName, const QString &envVarName,
const McuPackageVersionDetector *versionDetector) const McuPackageVersionDetector *versionDetector)
: McuPackage(label, defaultPath, detectionPath, settingsKey, envVarName, {}, versionDetector) : McuPackage(label, defaultPath, detectionPath, settingsKey, cmakeVarName, envVarName, {}, versionDetector)
, m_type(type) , m_type(type)
{} {}

View File

@@ -57,7 +57,8 @@ public:
const Utils::FilePath &defaultPath, const Utils::FilePath &defaultPath,
const Utils::FilePath &detectionPath, const Utils::FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
const QString &envVarName = {}, const QString &cmakeVarName,
const QString &envVarName,
const QString &downloadUrl = {}, const QString &downloadUrl = {},
const McuPackageVersionDetector *versionDetector = nullptr, const McuPackageVersionDetector *versionDetector = nullptr,
const bool addToPath = false, const bool addToPath = false,
@@ -66,6 +67,7 @@ public:
~McuPackage() override = default; ~McuPackage() override = default;
QString label() const override; QString label() const override;
const QString &cmakeVariableName() const override;
const QString &environmentVariableName() const override; const QString &environmentVariableName() const override;
bool isAddToSystemPath() const override; bool isAddToSystemPath() const override;
void setVersions(const QStringList &versions) override; void setVersions(const QStringList &versions) override;
@@ -103,6 +105,7 @@ private:
Utils::FilePath m_relativePathModifier; // relative path to m_path to be returned by path() Utils::FilePath m_relativePathModifier; // relative path to m_path to be returned by path()
QString m_detectedVersion; QString m_detectedVersion;
QStringList m_versions; QStringList m_versions;
const QString m_cmakeVariableName;
const QString m_environmentVariableName; const QString m_environmentVariableName;
const QString m_downloadUrl; const QString m_downloadUrl;
const bool m_addToSystemPath; const bool m_addToSystemPath;
@@ -120,6 +123,7 @@ public:
const Utils::FilePath &detectionPath, const Utils::FilePath &detectionPath,
const QString &settingsKey, const QString &settingsKey,
ToolChainType toolchainType, ToolChainType toolchainType,
const QString &cmakeVarName = {},
const QString &envVarName = {}, const QString &envVarName = {},
const McuPackageVersionDetector *versionDetector = nullptr); const McuPackageVersionDetector *versionDetector = nullptr);

View File

@@ -44,8 +44,6 @@ QtcPlugin {
"mcusupportrunconfiguration.h", "mcusupportrunconfiguration.h",
"mcusupportversiondetection.cpp", "mcusupportversiondetection.cpp",
"mcusupportversiondetection.h", "mcusupportversiondetection.h",
"mcusupportcmakemapper.h",
"mcusupportcmakemapper.cpp",
"mcutargetdescription.h", "mcutargetdescription.h",
"mcukitinformation.cpp", "mcukitinformation.cpp",
"mcukitinformation.h" "mcukitinformation.h"

View File

@@ -1,85 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "mcusupportcmakemapper.h"
#include "utils/namevalueitem.h"
#include <utils/algorithm.h>
namespace {
static const QHash<QString, QString> &envVarToCMakeVarMapping()
{
static const QHash<QString, QString> mapping = {
{"EVK_MIMXRT1060_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"EVK_MIMXRT1064_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"EVK_MIMXRT595_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"EVK_MIMXRT1170_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"EVKB_IMXRT1050_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"STM32Cube_FW_F7_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"STM32Cube_FW_F4_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"STM32Cube_FW_L4_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"STM32Cube_FW_H7_SDK_PATH", "QUL_BOARD_SDK_DIR"},
{"RGL_DIR", "QUL_BOARD_SDK_DIR"},
{"TVII_GRAPHICS_DRIVER_DIR", "QUL_BOARD_SDK_DIR"},
{"EK_RA6M3G_FSP_PATH", "QUL_BOARD_SDK_DIR"},
{"ARMGCC_DIR", "QUL_TARGET_TOOLCHAIN_DIR"},
{"IAR_ARM_COMPILER_DIR", "QUL_TARGET_TOOLCHAIN_DIR"},
{"GHS_COMPILER_DIR", "QUL_TARGET_TOOLCHAIN_DIR"},
{"GHS_ARM_COMPILER_DIR", "QUL_TARGET_TOOLCHAIN_DIR"},
{"EVK_MIMXRT1170_FREERTOS_PATH", "FREERTOS_DIR"},
{"IMXRT1050_FREERTOS_DIR", "FREERTOS_DIR"},
{"IMXRT1064_FREERTOS_DIR", "FREERTOS_DIR"},
{"IMXRT595_FREERTOS_DIR", "FREERTOS_DIR"},
{"STM32F7_FREERTOS_DIR", "FREERTOS_DIR"},
{"eFlashLoad_PATH", "eFlashLoad_PATH"},
{"RenesasFlashProgrammer_PATH", "RENESAS_FLASH_PROGRAMMER_PATH"},
{"MCUXpressoIDE_PATH", "MCUXPRESSO_IDE_PATH"},
{"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;
}
} // namespace
QList<CMakeProjectManager::CMakeConfigItem> McuSupport::Internal::mapEnvVarsToQul2xCmakeVars(
const Utils::EnvironmentItems &envVars)
{
const auto &mapping = envVarToCMakeVarMapping();
auto cmakeVars
= Utils::transform(envVars, [mapping](const Utils::EnvironmentItem &envVar) {
return CMakeProjectManager::CMakeConfigItem(mapping.value(envVar.name, "").toUtf8(),
envVar.value.toUtf8());
}).toList();
return Utils::filtered(cmakeVars, [](const CMakeProjectManager::CMakeConfigItem &item) {
return !item.key.isEmpty();
});
}
QString McuSupport::Internal::mapEnvVarToQul2xCmakeVar(const QString &envVar)
{
return envVarToCMakeVarMapping().value(envVar, QString());
}

View File

@@ -1,36 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "cmakeprojectmanager/cmakeconfigitem.h"
#include "utils/environmentfwd.h"
namespace McuSupport {
namespace Internal {
QList<CMakeProjectManager::CMakeConfigItem> mapEnvVarsToQul2xCmakeVars(
const Utils::EnvironmentItems &envVars);
QString mapEnvVarToQul2xCmakeVar(const QString &envVar);
}
} // namespace McuSupport

View File

@@ -307,7 +307,7 @@ void McuSupportOptionsWidget::apply()
if (pathsChanged) { if (pathsChanged) {
m_options.checkUpgradeableKits(); m_options.checkUpgradeableKits();
McuKitManager::fixKitsDependencies(); McuKitManager::updatePathsInExistingKits();
} }
} }
@@ -317,7 +317,7 @@ void McuSupportOptionsWidget::populateMcuTargetsComboBox()
m_mcuTargetsComboBox->clear(); m_mcuTargetsComboBox->clear();
m_mcuTargetsComboBox->addItems( m_mcuTargetsComboBox->addItems(
Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets, Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets,
[](McuTarget *t) { return McuKitManager::kitName(t); })); [](McuTarget *t) { return McuKitManager::generateKitNameFromTarget(t); }));
updateStatus(); updateStatus();
} }

View File

@@ -125,6 +125,7 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsSetup()
tr("Create Kits for Qt for MCUs? " tr("Create Kits for Qt for MCUs? "
"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
info.addCustomButton(tr("Create Kits for Qt for MCUs"), [setupMcuSupportKits] { info.addCustomButton(tr("Create Kits for Qt for MCUs"), [setupMcuSupportKits] {
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

@@ -74,6 +74,7 @@ McuPackage *createQtForMCUsPackage()
FileUtils::homePath(), // defaultPath FileUtils::homePath(), // defaultPath
FilePath("bin/qmltocpp").withExecutableSuffix(), // detectionPath FilePath("bin/qmltocpp").withExecutableSuffix(), // detectionPath
Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK, // settingsKey Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK, // settingsKey
QStringLiteral("Qul_ROOT"), // cmakeVarName
QStringLiteral("Qul_DIR")); // envVarName QStringLiteral("Qul_DIR")); // envVarName
} }
@@ -130,6 +131,7 @@ McuPackage *createBoardSdkPackage(const McuTargetDescription &desc)
defaultPath, defaultPath,
{}, // detection path {}, // detection path
desc.boardSdk.envVar, // settings key desc.boardSdk.envVar, // settings key
"QUL_BOARD_SDK_DIR", // cmake var
desc.boardSdk.envVar, // env var desc.boardSdk.envVar, // env var
{}, // download URL {}, // download URL
versionDetector); versionDetector);
@@ -147,12 +149,14 @@ McuPackage *createFreeRTOSSourcesPackage(const QString &envVar,
else if (!boardSdkDir.isEmpty() && !freeRTOSBoardSdkSubDir.isEmpty()) else if (!boardSdkDir.isEmpty() && !freeRTOSBoardSdkSubDir.isEmpty())
defaultPath = boardSdkDir / freeRTOSBoardSdkSubDir; defaultPath = boardSdkDir / freeRTOSBoardSdkSubDir;
return new McuPackage(QString{"FreeRTOS Sources (%1)"}.arg(envVarPrefix), return new McuPackage(QString::fromLatin1("FreeRTOS Sources (%1)").arg(envVarPrefix),
defaultPath, defaultPath,
{}, {}, // detection path
QString{"FreeRTOSSourcePackage_%1"}.arg(envVarPrefix), QString::fromLatin1("FreeRTOSSourcePackage_%1").arg(envVarPrefix), // settings key
envVar, "FREERTOS_DIR", // cmake var
"https://freertos.org"); envVar, // env var
"https://freertos.org"); // download url
} }
@@ -199,8 +203,9 @@ static McuToolChainPackage *createArmGccToolchainPackage()
defaultPath, defaultPath,
detectionPath, detectionPath,
"GNUArmEmbeddedToolchain", // settingsKey "GNUArmEmbeddedToolchain", // settingsKey
McuToolChainPackage::ToolChainType::ArmGcc, McuToolChainPackage::ToolChainType::ArmGcc, // toolchainType
envVar, "QUL_TARGET_TOOLCHAIN_DIR", // cmake var
envVar, // env var
versionDetector); versionDetector);
} }
@@ -219,8 +224,9 @@ static McuToolChainPackage *createGhsToolchainPackage()
defaultPath, defaultPath,
FilePath("ccv850").withExecutableSuffix(), // detectionPath FilePath("ccv850").withExecutableSuffix(), // detectionPath
"GHSToolchain", // settingsKey "GHSToolchain", // settingsKey
McuToolChainPackage::ToolChainType::GHS, McuToolChainPackage::ToolChainType::GHS, // toolchainType
envVar, "QUL_TARGET_TOOLCHAIN_DIR", // cmake var
envVar, // env var
versionDetector); versionDetector);
} }
@@ -239,8 +245,9 @@ static McuToolChainPackage *createGhsArmToolchainPackage()
defaultPath, defaultPath,
FilePath("cxarm").withExecutableSuffix(), // detectionPath FilePath("cxarm").withExecutableSuffix(), // detectionPath
"GHSArmToolchain", // settingsKey "GHSArmToolchain", // settingsKey
McuToolChainPackage::ToolChainType::GHSArm, McuToolChainPackage::ToolChainType::GHSArm, // toolchainType
envVar, "QUL_TARGET_TOOLCHAIN_DIR", // cmake var
envVar, // env var
versionDetector); versionDetector);
} }
@@ -272,8 +279,9 @@ static McuToolChainPackage *createIarToolChainPackage()
defaultPath, defaultPath,
detectionPath, detectionPath,
"IARToolchain", // settings key "IARToolchain", // settings key
McuToolChainPackage::ToolChainType::IAR, McuToolChainPackage::ToolChainType::IAR, // toolchainType
envVar, "QUL_TARGET_TOOLCHAIN_DIR", // cmake var
envVar, // env var
versionDetector); versionDetector);
} }
@@ -302,6 +310,7 @@ static McuPackage *createStm32CubeProgrammerPackage()
defaultPath, defaultPath,
detectionPath, detectionPath,
"Stm32CubeProgrammer", "Stm32CubeProgrammer",
{}, // cmake var
{}, // env var {}, // env var
"https://www.st.com/en/development-tools/stm32cubeprog.html", // download url "https://www.st.com/en/development-tools/stm32cubeprog.html", // download url
nullptr, // version detector nullptr, // version detector
@@ -338,6 +347,7 @@ static McuPackage *createMcuXpressoIdePackage()
defaultPath, defaultPath,
FilePath("ide/binaries/crt_emu_cm_redlink").withExecutableSuffix(), // detection path FilePath("ide/binaries/crt_emu_cm_redlink").withExecutableSuffix(), // detection path
"MCUXpressoIDE", // settings key "MCUXpressoIDE", // settings key
"MCUXPRESSO_IDE_PATH", // cmake var
envVar, envVar,
"https://www.nxp.com/mcuxpresso/ide"); // download url "https://www.nxp.com/mcuxpresso/ide"); // download url
} }
@@ -363,8 +373,9 @@ static McuPackage *createCypressProgrammerPackage()
auto result = new McuPackage("Cypress Auto Flash Utility", auto result = new McuPackage("Cypress Auto Flash Utility",
defaultPath, defaultPath,
FilePath("/bin/openocd").withExecutableSuffix(), FilePath("/bin/openocd").withExecutableSuffix(),
"CypressAutoFlashUtil", "CypressAutoFlashUtil", // settings key
envVar); "INFINEON_AUTO_FLASH_UTILITY_DIR", // cmake var
envVar); // env var
return result; return result;
} }
@@ -389,8 +400,9 @@ static McuPackage *createRenesasProgrammerPackage()
auto result = new McuPackage("Renesas Flash Programmer", auto result = new McuPackage("Renesas Flash Programmer",
defaultPath, defaultPath,
FilePath("rfp-cli").withExecutableSuffix(), FilePath("rfp-cli").withExecutableSuffix(),
"RenesasFlashProgrammer", "RenesasFlashProgrammer", // settings key
envVar); "RENESAS_FLASH_PROGRAMMER_PATH", // cmake var
envVar); // env var
return result; return result;
} }
@@ -596,7 +608,7 @@ void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo)
std::sort(repo->mcuTargets.begin(), std::sort(repo->mcuTargets.begin(),
repo->mcuTargets.end(), repo->mcuTargets.end(),
[](const McuTarget *lhs, const McuTarget *rhs) { [](const McuTarget *lhs, const McuTarget *rhs) {
return McuKitManager::kitName(lhs) < McuKitManager::kitName(rhs); return McuKitManager::generateKitNameFromTarget(lhs) < McuKitManager::generateKitNameFromTarget(rhs);
}); });
} }

View File

@@ -82,13 +82,13 @@ void McuTarget::printPackageProblems() const
package->updateStatus(); package->updateStatus();
if (!package->isValidStatus()) if (!package->isValidStatus())
printMessage(tr("Error creating kit for target %1, package %2: %3") printMessage(tr("Error creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this), .arg(McuKitManager::generateKitNameFromTarget(this),
package->label(), package->label(),
package->statusText()), package->statusText()),
true); true);
if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion) if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion)
printMessage(tr("Warning creating kit for target %1, package %2: %3") printMessage(tr("Warning creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this), .arg(McuKitManager::generateKitNameFromTarget(this),
package->label(), package->label(),
package->statusText()), package->statusText()),
false); false);

View File

@@ -46,6 +46,7 @@ public:
MOCK_METHOD(Status, status, (), (const)); MOCK_METHOD(Status, status, (), (const));
MOCK_METHOD(bool, isValidStatus, (), (const)); MOCK_METHOD(bool, isValidStatus, (), (const));
MOCK_METHOD(const QString &, cmakeVariableName, (), (const));
MOCK_METHOD(const QString &, environmentVariableName, (), (const)); MOCK_METHOD(const QString &, environmentVariableName, (), (const));
MOCK_METHOD(bool, isAddToSystemPath, (), (const)); MOCK_METHOD(bool, isAddToSystemPath, (), (const));
MOCK_METHOD(bool, writeToSettings, (), (const)); MOCK_METHOD(bool, writeToSettings, (), (const));

View File

@@ -47,6 +47,7 @@
namespace McuSupport::Internal::Test { namespace McuSupport::Internal::Test {
// clazy:excludeall=non-pod-global-static
static const QString nxp1050FreeRtosEnvVar{"IMXRT1050_FREERTOS_DIR"}; static const QString nxp1050FreeRtosEnvVar{"IMXRT1050_FREERTOS_DIR"};
static const QString nxp1064FreeRtosEnvVar{"IMXRT1064_FREERTOS_DIR"}; static const QString nxp1064FreeRtosEnvVar{"IMXRT1064_FREERTOS_DIR"};
static const QString nxp1170FreeRtosEnvVar{"EVK_MIMXRT1170_FREERTOS_PATH"}; static const QString nxp1170FreeRtosEnvVar{"EVK_MIMXRT1170_FREERTOS_PATH"};
@@ -69,10 +70,6 @@ using Utils::FilePath;
void McuSupportTest::initTestCase() void McuSupportTest::initTestCase()
{ {
EXPECT_CALL(freeRtosPackage, environmentVariableName()).WillRepeatedly(ReturnRef(freeRtosEnvVar));
EXPECT_CALL(freeRtosPackage, isValidStatus()).WillRepeatedly(Return(true));
EXPECT_CALL(freeRtosPackage, path())
.WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath)));
} }
void McuSupportTest::test_parseBasicInfoFromJson() void McuSupportTest::test_parseBasicInfoFromJson()
@@ -85,11 +82,35 @@ void McuSupportTest::test_parseBasicInfoFromJson()
void McuSupportTest::test_addNewKit() void McuSupportTest::test_addNewKit()
{ {
const QString cmakeVar = "CMAKE_SDK";
McuPackage sdkPackage{"sdk", // label
{}, // defaultPath
{}, // detectionPath
"sdk", // settingsKey
cmakeVar, // cmake var
{}}; // env var
Kit kit;
McuToolChainPackage toolchainPackage{
{}, // label
{}, // defaultPath
{}, // detectionPath
{}, // settingsKey
McuToolChainPackage::ToolChainType::Unsupported, // toolchain type
{}, // cmake var name
{}}; // env var name
const McuTarget::Platform platform{id, name, vendor};
McuTarget mcuTarget{currentQulVersion, // version
platform, // platform
McuTarget::OS::FreeRTOS, // os
{&sdkPackage}, // 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, &freeRtosPackage)}; auto *newKit{McuKitManager::newKit(&mcuTarget, &sdkPackage)};
QVERIFY(newKit != nullptr); QVERIFY(newKit != nullptr);
QCOMPARE(kitAddedSpy.count(), 1); QCOMPARE(kitAddedSpy.count(), 1);
@@ -98,26 +119,11 @@ void McuSupportTest::test_addNewKit()
QVERIFY(createdKit != nullptr); QVERIFY(createdKit != nullptr);
QCOMPARE(createdKit, newKit); QCOMPARE(createdKit, newKit);
auto cmakeAspect{CMakeConfigurationKitAspect{}}; const auto config = CMakeConfigurationKitAspect::configuration(newKit);
QVERIFY(createdKit->hasValue(cmakeAspect.id())); QVERIFY(config.size() > 0);
QVERIFY(createdKit->value(cmakeAspect.id(), freeRtosCmakeVar).isValid()); QVERIFY(Utils::indexOf(config.toVector(), [&cmakeVar](const CMakeConfigItem &item) {
} return item.key == cmakeVar.toUtf8();
}) != -1);
void McuSupportTest::test_addFreeRtosCmakeVarToKit()
{
McuKitManager::updateKitEnvironment(&kit, &mcuTarget);
QVERIFY(kit.hasValue(EnvironmentKitAspect::id()));
QVERIFY(kit.isValid());
QVERIFY(!kit.allKeys().empty());
const auto &cmakeConfig{CMakeConfigurationKitAspect::configuration(&kit)};
QCOMPARE(cmakeConfig.size(), 1);
CMakeConfigItem
expectedCmakeVar{freeRtosCmakeVar.toLocal8Bit(),
FilePath::fromString(defaultfreeRtosPath).toUserOutput().toLocal8Bit()};
QVERIFY(cmakeConfig.contains(expectedCmakeVar));
} }
void McuSupportTest::test_createPackagesWithCorrespondingSettings_data() void McuSupportTest::test_createPackagesWithCorrespondingSettings_data()
@@ -160,6 +166,8 @@ void McuSupportTest::test_createPackagesWithCorrespondingSettings()
QFETCH(QString, json); QFETCH(QString, json);
const auto description = Sdk::parseDescriptionJson(json.toLocal8Bit()); const auto description = Sdk::parseDescriptionJson(json.toLocal8Bit());
QVector<McuAbstractPackage *> packages; QVector<McuAbstractPackage *> packages;
const auto targets = Sdk::targetsFromDescriptions({description}, &packages);
Q_UNUSED(targets);
QSet<QString> settings = Utils::transform<QSet<QString>>(packages, [](const auto &package) { QSet<QString> settings = Utils::transform<QSet<QString>>(packages, [](const auto &package) {
return package->settingsKey(); return package->settingsKey();

View File

@@ -52,7 +52,6 @@ class McuSupportTest : public QObject
private slots: private slots:
void initTestCase(); void initTestCase();
void test_addFreeRtosCmakeVarToKit();
void test_addNewKit(); void test_addNewKit();
void test_parseBasicInfoFromJson(); void test_parseBasicInfoFromJson();
void test_createPackagesWithCorrespondingSettings(); void test_createPackagesWithCorrespondingSettings();
@@ -69,17 +68,6 @@ private:
const QString freeRtosCmakeVar{"FREERTOS_DIR"}; const QString freeRtosCmakeVar{"FREERTOS_DIR"};
const QString defaultfreeRtosPath{"/opt/freertos/default"}; const QString defaultfreeRtosPath{"/opt/freertos/default"};
PackageMock freeRtosPackage;
Kit kit;
McuToolChainPackage toolchainPackage{{}, {}, {}, {}, {}};
const McuTarget::Platform platform{id, name, vendor};
McuTarget mcuTarget{currentQulVersion,
platform,
McuTarget::OS::FreeRTOS,
{&freeRtosPackage},
&toolchainPackage};
}; // class McuSupportTest }; // class McuSupportTest
} // namespace McuSupport::Internal::Test } // namespace McuSupport::Internal::Test