McuSupport: split mcusupportoptions

Several independent classes were mashed together in mcusupportoptions.cpp
This patch moves McuToolChainPackage together with McuPackage,
McuTarget to its own header+source pair, and
McuKitManager to its own header+source pair.

Task-number: QTCREATORBUG-26890
Change-Id: I0b51da4e1cae5a976201dffd290a665eaa318b33
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Christiaan Janssen
2022-02-16 16:48:28 +01:00
parent a08e0f7a9d
commit 2834e90930
16 changed files with 1120 additions and 745 deletions

View File

@@ -8,8 +8,10 @@ add_qtc_plugin(McuSupport
mcusupportconstants.h mcusupportconstants.h
mcusupportdevice.cpp mcusupportdevice.h mcusupportdevice.cpp mcusupportdevice.h
mcusupportoptions.cpp mcusupportoptions.h mcuabstractpackage.h mcusupportoptions.cpp mcusupportoptions.h mcuabstractpackage.h
mcukitmanager.cpp mcukitmanager.h
mcusupportoptionspage.cpp mcusupportoptionspage.h mcusupportoptionspage.cpp mcusupportoptionspage.h
mcupackage.cpp mcupackage.h mcupackage.cpp mcupackage.h
mcutarget.cpp mcutarget.h
mcusupportplugin.cpp mcusupportplugin.h mcusupportplugin.cpp mcusupportplugin.h
mcusupportsdk.cpp mcusupportsdk.h mcusupportsdk.cpp mcusupportsdk.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h

View File

@@ -0,0 +1,596 @@
/****************************************************************************
**
** Copyright (C) 2020 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 "mcukitmanager.h"
#include "mcusupportoptions.h"
#include "mcusupportconstants.h"
#include "mcukitinformation.h"
#include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h"
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketoolmanager.h>
#include <coreplugin/icore.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <debugger/debuggerkitinformation.h>
#include <utils/algorithm.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtversionmanager.h>
#include <QMessageBox>
#include <QPushButton>
using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect;
using namespace ProjectExplorer;
using namespace Utils;
namespace McuSupport {
namespace Internal {
namespace McuKitManager {
static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change
static FilePath qulDocsDir()
{
const FilePath qulDir = McuSupportOptions::qulDirFromSettings();
if (qulDir.isEmpty() || !qulDir.exists())
return {};
const FilePath docsDir = qulDir.pathAppended("docs");
return docsDir.exists() ? docsDir : FilePath();
}
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{
switch (tcPackage->type()) {
case McuToolChainPackage::Type::Unsupported:
return;
case McuToolChainPackage::Type::GHS:
case McuToolChainPackage::Type::GHSArm:
return; // No Green Hills toolchain, because support for it is missing.
case McuToolChainPackage::Type::IAR:
case McuToolChainPackage::Type::KEIL:
case McuToolChainPackage::Type::MSVC:
case McuToolChainPackage::Type::GCC:
case McuToolChainPackage::Type::ArmGcc:
ToolChainKitAspect::setToolChain(k,
tcPackage->toolChain(
ProjectExplorer::Constants::C_LANGUAGE_ID));
ToolChainKitAspect::setToolChain(k,
tcPackage->toolChain(
ProjectExplorer::Constants::CXX_LANGUAGE_ID));
return;
default:
Q_UNREACHABLE();
}
}
static void setKitProperties(const QString &kitName,
Kit *k,
const McuTarget *mcuTarget,
const FilePath &sdkPath)
{
using namespace Constants;
k->setUnexpandedDisplayName(kitName);
k->setValue(KIT_MCUTARGET_VENDOR_KEY, mcuTarget->platform().vendor);
k->setValue(KIT_MCUTARGET_MODEL_KEY, mcuTarget->platform().name);
k->setValue(KIT_MCUTARGET_COLORDEPTH_KEY, mcuTarget->colorDepth());
k->setValue(KIT_MCUTARGET_SDKVERSION_KEY, mcuTarget->qulVersion().toString());
k->setValue(KIT_MCUTARGET_KITVERSION_KEY, KIT_VERSION);
k->setValue(KIT_MCUTARGET_OS_KEY, static_cast<int>(mcuTarget->os()));
k->setValue(KIT_MCUTARGET_TOOCHAIN_KEY, mcuTarget->toolChainPackage()->toolChainName());
k->setAutoDetected(false);
k->makeSticky();
if (mcuTarget->toolChainPackage()->isDesktopToolchain())
k->setDeviceTypeForIcon(DEVICE_TYPE);
k->setValue(QtSupport::SuppliesQtQuickImportPath::id(), true);
k->setValue(QtSupport::KitQmlImportPath::id(), sdkPath.pathAppended("include/qul").toVariant());
k->setValue(QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(), true);
QSet<Id> irrelevant = {
SysRootKitAspect::id(),
QtSupport::SuppliesQtQuickImportPath::id(),
QtSupport::KitQmlImportPath::id(),
QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(),
};
if (!McuSupportOptions::kitsNeedQtVersion())
irrelevant.insert(QtSupport::QtKitAspect::id());
k->setIrrelevantAspects(irrelevant);
}
static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
{
if (tcPackage->isDesktopToolchain()) {
// Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain
return;
}
switch (tcPackage->type()) {
case McuToolChainPackage::Type::Unsupported:
case McuToolChainPackage::Type::GHS:
case McuToolChainPackage::Type::GHSArm:
case McuToolChainPackage::Type::IAR:
return; // No Green Hills and IAR debugger, because support for it is missing.
case McuToolChainPackage::Type::KEIL:
case McuToolChainPackage::Type::MSVC:
case McuToolChainPackage::Type::GCC:
case McuToolChainPackage::Type::ArmGcc: {
const QVariant debuggerId = tcPackage->debuggerId();
if (debuggerId.isValid()) {
Debugger::DebuggerKitAspect::setDebugger(k, debuggerId);
}
return;
}
default:
Q_UNREACHABLE();
}
}
static void setKitDevice(Kit *k, const McuTarget *mcuTarget)
{
// "Device Type" Desktop is the default. We use that for the Qt for MCUs Desktop Kit
if (mcuTarget->toolChainPackage()->isDesktopToolchain())
return;
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
}
static bool expectsCmakeVars(const McuTarget *mcuTarget)
{
return mcuTarget->qulVersion() >= QVersionNumber{2, 0};
}
static void setKitDependencies(Kit *k,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
NameValueItems dependencies;
auto processPackage = [&dependencies](const McuAbstractPackage *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 FilePath &qulDir)
{
using namespace CMakeProjectManager;
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
if (mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHS
&& mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHSArm) {
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
}
if (!mcuTarget->toolChainPackage()->isDesktopToolchain()) {
const FilePath cMakeToolchainFile = qulDir.pathAppended(
"lib/cmake/Qul/toolchain/" + mcuTarget->toolChainPackage()->cmakeToolChainFileName());
config.append(
CMakeConfigItem("CMAKE_TOOLCHAIN_FILE", cMakeToolchainFile.toString().toUtf8()));
if (!cMakeToolchainFile.exists()) {
printMessage(McuTarget::tr(
"Warning for target %1: missing CMake toolchain file expected at %2.")
.arg(kitName(mcuTarget),
cMakeToolchainFile.toUserOutput()),
false);
}
}
const FilePath generatorsPath = qulDir.pathAppended("/lib/cmake/Qul/QulGenerators.cmake");
config.append(CMakeConfigItem("QUL_GENERATORS", generatorsPath.toString().toUtf8()));
if (!generatorsPath.exists()) {
printMessage(McuTarget::tr("Warning for target %1: missing QulGenerators expected at %2.")
.arg(kitName(mcuTarget), generatorsPath.toUserOutput()),
false);
}
config.append(CMakeConfigItem("QUL_PLATFORM", mcuTarget->platform().name.toUtf8()));
if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
QString::number(mcuTarget->colorDepth()).toLatin1()));
if (McuSupportOptions::kitsNeedQtVersion())
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
CMakeConfigurationKitAspect::setConfiguration(k, config);
if (HostOsInfo::isWindowsHost()) {
auto type = mcuTarget->toolChainPackage()->type();
if (type == McuToolChainPackage::Type::GHS || type == McuToolChainPackage::Type::GHSArm) {
// 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
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
}
}
}
static void setKitQtVersionOptions(Kit *k)
{
if (!McuSupportOptions::kitsNeedQtVersion())
QtSupport::QtKitAspect::setQtVersion(k, nullptr);
// else: auto-select a Qt version
}
QString kitName(const McuTarget *mcuTarget)
{
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
? QString::fromLatin1(" (%1)").arg(
tcPkg->toolChainName().toUpper())
: "";
const QString colorDepth = mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
: "";
const QString targetName = mcuTarget->platform().displayName.isEmpty()
? mcuTarget->platform().name
: mcuTarget->platform().displayName;
return QString::fromLatin1("Qt for MCUs %1.%2 - %3%4%5")
.arg(QString::number(mcuTarget->qulVersion().majorVersion()),
QString::number(mcuTarget->qulVersion().minorVersion()),
targetName,
colorDepth,
compilerName);
}
QList<Kit *> existingKits(const McuTarget *mcuTarget)
{
using namespace Constants;
return Utils::filtered(KitManager::kits(), [mcuTarget](Kit *kit) {
return kit->value(KIT_MCUTARGET_KITVERSION_KEY) == KIT_VERSION
&& (!mcuTarget
|| (kit->value(KIT_MCUTARGET_VENDOR_KEY) == mcuTarget->platform().vendor
&& kit->value(KIT_MCUTARGET_MODEL_KEY) == mcuTarget->platform().name
&& kit->value(KIT_MCUTARGET_COLORDEPTH_KEY) == mcuTarget->colorDepth()
&& kit->value(KIT_MCUTARGET_OS_KEY).toInt()
== static_cast<int>(mcuTarget->os())
&& kit->value(KIT_MCUTARGET_TOOCHAIN_KEY)
== mcuTarget->toolChainPackage()->toolChainName()));
});
}
QList<Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return !kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget](Kit *kit) {
const auto environment = Utils::NameValueDictionary(
Utils::NameValueItem::toStringList(EnvironmentKitAspect::environmentChanges(kit)));
return Utils::anyOf(mcuTarget->packages(),
[&environment](const McuAbstractPackage *package) {
return !package->environmentVariableName().isEmpty()
&& environment.value(package->environmentVariableName())
!= package->path().toUserOutput();
});
});
}
QList<Kit *> outdatedKits()
{
return Utils::filtered(KitManager::kits(), [](Kit *kit) {
return !kit->value(Constants::KIT_MCUTARGET_VENDOR_KEY).isNull()
&& kit->value(Constants::KIT_MCUTARGET_KITVERSION_KEY) != KIT_VERSION;
});
}
void removeOutdatedKits()
{
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());
McuSupportOptions::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()
{
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
const auto createKits = [qtForMCUsPackage]() {
if (qtForMCUsPackage->automaticKitCreationEnabled()) {
qtForMCUsPackage->updateStatus();
if (!qtForMCUsPackage->validStatus()) {
switch (qtForMCUsPackage->status()) {
case McuAbstractPackage::Status::ValidPathInvalidPackage: {
const QString displayPath
= FilePath::fromString(qtForMCUsPackage->detectionPath()).toUserOutput();
printMessage(McuPackage::tr("Path %1 exists, but does not contain %2.")
.arg(qtForMCUsPackage->path().toUserOutput(), displayPath),
true);
break;
}
case McuAbstractPackage::Status::InvalidPath: {
printMessage(McuPackage::tr("Path %1 does not exist. Add the path in Tools > Options > "
"Devices > MCU.")
.arg(qtForMCUsPackage->path().toUserOutput()),
true);
break;
}
case McuAbstractPackage::Status::EmptyPath: {
printMessage(McuPackage::tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath()),
true);
return;
}
default:
break;
}
return;
}
if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) {
printMessage(McuPackage::tr("No CMake tool was detected. Add a CMake tool in Tools > Options > "
"Kits > CMake."),
true);
return;
}
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
bool needsUpgrade = false;
for (const auto &target : qAsConst(repo.mcuTargets)) {
// if kit already exists, skip
if (!matchingKits(target, qtForMCUsPackage).empty())
continue;
if (!upgradeableKits(target, qtForMCUsPackage).empty()) {
// if kit exists but wrong version/path
needsUpgrade = true;
} else {
// if no kits for this target, create
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
if (needsUpgrade)
McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade();
}
};
createKits();
delete qtForMCUsPackage;
}
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
{
if (upgradeOption == UpgradeOption::Ignore)
return;
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
auto dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (!matchingKits(target, qtForMCUsPackage).empty())
// already up-to-date
continue;
const auto kits = upgradeableKits(target, qtForMCUsPackage);
if (!kits.empty()) {
if (upgradeOption == UpgradeOption::Replace) {
for (auto existingKit : kits)
KitManager::deregisterKit(existingKit);
}
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk)
{
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path());
McuSupportOptions::setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
setKitDependencies(kit, mcuTarget, qtForMCUsSdk);
}
void fixKitsDependencies()
{
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (target->isValid()) {
for (auto *kit : kitsWithMismatchedDependencies(target)) {
McuSupportOptions::updateKitEnvironment(kit, target);
}
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
/**
* @brief Fix/update existing kits if needed
*/
void fixExistingKits()
{
for (Kit *kit : KitManager::kits()) {
if (!kit->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY))
continue;
if (kit->isAutoDetected()) {
kit->setAutoDetected(false);
}
// Check if the MCU kits are flagged as supplying a QtQuick import path, in order
// to tell the QMLJS code-model that it won't need to add a fall-back import
// path.
const auto bringsQtQuickImportPath = QtSupport::SuppliesQtQuickImportPath::id();
auto irrelevantAspects = kit->irrelevantAspects();
if (!irrelevantAspects.contains(bringsQtQuickImportPath)) {
irrelevantAspects.insert(bringsQtQuickImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(bringsQtQuickImportPath)) {
kit->setValue(bringsQtQuickImportPath, true);
}
// Check if the MCU kit supplies its import path.
const auto kitQmlImportPath = QtSupport::KitQmlImportPath::id();
if (!irrelevantAspects.contains(kitQmlImportPath)) {
irrelevantAspects.insert(kitQmlImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(kitQmlImportPath)) {
auto config = CMakeProjectManager::CMakeConfigurationKitAspect::configuration(kit);
for (const auto &cfgItem : qAsConst(config)) {
if (cfgItem.key == "QUL_GENERATORS") {
auto idx = cfgItem.value.indexOf("/lib/cmake/Qul");
auto qulDir = cfgItem.value.left(idx);
kit->setValue(kitQmlImportPath, QVariant(qulDir + "/include/qul"));
break;
}
}
}
// Check if the MCU kit has the flag for merged header/qml-import paths set.
const auto mergedPaths = QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id();
if (!irrelevantAspects.contains(mergedPaths)) {
irrelevantAspects.insert(mergedPaths);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->value(mergedPaths, false).toBool()) {
kit->setValue(mergedPaths, true);
}
}
// Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->validStatus()) {
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets))
for (auto kit : existingKits(target)) {
if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) {
setKitDependencies(kit, target, qtForMCUsPackage);
}
}
repo.deletePackagesAndTargets();
}
delete qtForMCUsPackage;
}
} // namespace McuKitManager
} // namespace Internal
} // namespace McuSupport

View File

@@ -0,0 +1,86 @@
/****************************************************************************
**
** Copyright (C) 2022 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 <utils/environmentfwd.h>
#include "mcusupport_global.h"
#include <QCoreApplication>
#include <QObject>
#include <QVector>
#include <QVersionNumber>
namespace ProjectExplorer {
class Kit;
} // namespace ProjectExplorer
namespace McuSupport {
namespace Internal {
class McuAbstractPackage;
class McuToolChainPackage;
class McuTarget;
namespace McuKitManager
{
enum class UpgradeOption {
Ignore,
Keep,
Replace
};
// Creating kits:
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
void createAutomaticKits();
// Querying the kits:
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
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);
// Upgrading kits:
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption);
void upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
// Fixing kits:
void fixKitsDependencies();
void fixExistingKits();
// Outdated kits:
QList<ProjectExplorer::Kit *> outdatedKits();
void removeOutdatedKits();
// Querying kits:
QString kitName(const McuTarget* mcuTarget);
QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
bool kitIsUpToDate(const ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
} // namespace McuKitManager
} // namespace Internal
} // namespace McuSupport

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -25,6 +25,7 @@
#include "mcupackage.h" #include "mcupackage.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportversiondetection.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -314,4 +315,5 @@ bool McuToolChainPackage::isDesktopToolchain() const
return m_type == Type::MSVC || m_type == Type::GCC; return m_type == Type::MSVC || m_type == Type::GCC;
} }
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -26,10 +26,8 @@
#pragma once #pragma once
#include "mcuabstractpackage.h" #include "mcuabstractpackage.h"
#include "mcusupportversiondetection.h"
#include <utils/filepath.h> #include <utils/filepath.h>
#include <utils/id.h>
#include <QObject> #include <QObject>
@@ -42,11 +40,14 @@ class ToolChain;
namespace Utils { namespace Utils {
class PathChooser; class PathChooser;
class InfoLabel; class InfoLabel;
class Id;
} // namespace Utils } // namespace Utils
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
class McuPackageVersionDetector;
class McuPackage : public McuAbstractPackage class McuPackage : public McuAbstractPackage
{ {
Q_OBJECT Q_OBJECT

View File

@@ -18,6 +18,8 @@ QtcPlugin {
"mcuabstractpackage.h", "mcuabstractpackage.h",
"mcupackage.cpp", "mcupackage.cpp",
"mcupackage.h", "mcupackage.h",
"mcutarget.cpp",
"mcutarget.h",
"mcusupport.qrc", "mcusupport.qrc",
"mcusupport_global.h", "mcusupport_global.h",
"mcusupportconstants.h", "mcusupportconstants.h",
@@ -25,6 +27,8 @@ QtcPlugin {
"mcusupportdevice.h", "mcusupportdevice.h",
"mcusupportoptions.cpp", "mcusupportoptions.cpp",
"mcusupportoptions.h", "mcusupportoptions.h",
"mcukitmanager.cpp",
"mcukitmanager.h",
"mcusupportoptionspage.cpp", "mcusupportoptionspage.cpp",
"mcusupportoptionspage.h", "mcusupportoptionspage.h",
"mcusupportplugin.cpp", "mcusupportplugin.cpp",

View File

@@ -25,47 +25,26 @@
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcukitinformation.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcutarget.h"
#include "mcukitmanager.h"
#include "mcukitinformation.h"
#include "mcusupportcmakemapper.h" #include "mcusupportcmakemapper.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h>
#include <cmakeprojectmanager/cmakekitinformation.h> #include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketoolmanager.h> #include <cmakeprojectmanager/cmaketoolmanager.h>
#include <coreplugin/helpmanager.h> #include <coreplugin/helpmanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <debugger/debuggerkitinformation.h> #include <debugger/debuggerkitinformation.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/infolabel.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtversionmanager.h> #include <qtsupport/qtversionmanager.h>
#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QLabel>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
using CMakeProjectManager::CMakeConfigItem; using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect; using CMakeProjectManager::CMakeConfigurationKitAspect;
@@ -75,261 +54,6 @@ using namespace Utils;
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change
static bool kitNeedsQtVersion()
{
// Only on Windows, Qt is linked into the distributed qul Desktop libs. Also, the host tools
// are missing the Qt runtime libraries on non-Windows.
return !HostOsInfo::isWindowsHost();
}
static ToolChain *msvcToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor
|| abi.osFlavor() == Abi::WindowsMsvc2019Flavor)
&& abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64
&& t->language() == language;
});
return toolChain;
}
static ToolChain *gccToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture
&& abi.wordWidth() == 64 && t->language() == language;
});
return toolChain;
}
static ToolChain *armGccToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) {
return t->compilerCommand() == path && t->language() == language;
});
if (!toolChain) {
ToolChainFactory *gccFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
});
if (gccFactory) {
const QList<ToolChain *> detected = gccFactory->detectForImport({path, language});
if (!detected.isEmpty()) {
toolChain = detected.first();
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("Arm GCC");
ToolChainManager::registerToolChain(toolChain);
}
}
}
return toolChain;
}
static ToolChain *iarToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID
&& t->language() == language;
});
if (!toolChain) {
ToolChainFactory *iarFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
});
if (iarFactory) {
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
if (detected.isEmpty())
detected = iarFactory->detectForImport({path, language});
for (auto tc : detected) {
if (tc->language() == language) {
toolChain = tc;
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("IAREW");
ToolChainManager::registerToolChain(toolChain);
}
}
}
}
return toolChain;
}
ToolChain *McuToolChainPackage::toolChain(Id language) const
{
switch (m_type) {
case Type::MSVC:
return msvcToolChain(language);
case Type::GCC:
return gccToolChain(language);
case Type::IAR: {
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
return iarToolChain(compiler, language);
}
case Type::ArmGcc:
case Type::KEIL:
case Type::GHS:
case Type::GHSArm:
case Type::Unsupported: {
const QLatin1String compilerName(
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
const QString comp = QLatin1String(m_type == Type::ArmGcc ? "/bin/arm-none-eabi-%1"
: "/bar/foo-keil-%1")
.arg(compilerName);
const FilePath compiler = path().pathAppended(comp).withExecutableSuffix();
return armGccToolChain(compiler, language);
}
default:
Q_UNREACHABLE();
}
}
QString McuToolChainPackage::toolChainName() const
{
switch (m_type) {
case Type::ArmGcc:
return QLatin1String("armgcc");
case Type::IAR:
return QLatin1String("iar");
case Type::KEIL:
return QLatin1String("keil");
case Type::GHS:
return QLatin1String("ghs");
case Type::GHSArm:
return QLatin1String("ghs-arm");
default:
return QLatin1String("unsupported");
}
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
}
QVariant McuToolChainPackage::debuggerId() const
{
using namespace Debugger;
QString sub, displayName;
DebuggerEngineType engineType;
switch (m_type) {
case Type::ArmGcc: {
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
displayName = McuPackage::tr("Arm GDB at %1");
engineType = Debugger::GdbEngineType;
break;
}
case Type::IAR: {
sub = QString::fromLatin1("../common/bin/CSpyBat");
displayName = QLatin1String("CSpy");
engineType = Debugger::NoEngineType; // support for IAR missing
break;
}
case Type::KEIL: {
sub = QString::fromLatin1("UV4/UV4");
displayName = QLatin1String("KEIL uVision Debugger");
engineType = Debugger::UvscEngineType;
break;
}
default:
return QVariant();
}
const FilePath command = path().pathAppended(sub).withExecutableSuffix();
if (const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command)) {
return debugger->id();
}
DebuggerItem newDebugger;
newDebugger.setCommand(command);
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
newDebugger.setEngineType(engineType);
return DebuggerItemManager::registerDebugger(newDebugger);
}
McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth)
: m_qulVersion(qulVersion)
, m_platform(platform)
, m_os(os)
, m_packages(packages)
, m_toolChainPackage(toolChainPackage)
, m_colorDepth(colorDepth)
{}
const QVector<McuAbstractPackage *> &McuTarget::packages() const
{
return m_packages;
}
const McuToolChainPackage *McuTarget::toolChainPackage() const
{
return m_toolChainPackage;
}
McuTarget::OS McuTarget::os() const
{
return m_os;
}
const McuTarget::Platform &McuTarget::platform() const
{
return m_platform;
}
bool McuTarget::isValid() const
{
return Utils::allOf(packages(), [](McuAbstractPackage *package) {
package->updateStatus();
return package->validStatus();
});
}
void McuTarget::printPackageProblems() const
{
for (auto package : packages()) {
package->updateStatus();
if (!package->validStatus())
printMessage(tr("Error creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this),
package->label(),
package->statusText()),
true);
if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion)
printMessage(tr("Warning creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this),
package->label(),
package->statusText()),
false);
}
}
const QVersionNumber &McuTarget::qulVersion() const
{
return m_qulVersion;
}
int McuTarget::colorDepth() const
{
return m_colorDepth;
}
void McuSdkRepository::deletePackagesAndTargets() void McuSdkRepository::deletePackagesAndTargets()
{ {
qDeleteAll(packages); qDeleteAll(packages);
@@ -423,39 +147,6 @@ FilePath McuSupportOptions::qulDirFromSettings()
QSettings::UserScope, {}); QSettings::UserScope, {});
} }
static void setKitProperties(const QString &kitName,
Kit *k,
const McuTarget *mcuTarget,
const FilePath &sdkPath)
{
using namespace Constants;
k->setUnexpandedDisplayName(kitName);
k->setValue(KIT_MCUTARGET_VENDOR_KEY, mcuTarget->platform().vendor);
k->setValue(KIT_MCUTARGET_MODEL_KEY, mcuTarget->platform().name);
k->setValue(KIT_MCUTARGET_COLORDEPTH_KEY, mcuTarget->colorDepth());
k->setValue(KIT_MCUTARGET_SDKVERSION_KEY, mcuTarget->qulVersion().toString());
k->setValue(KIT_MCUTARGET_KITVERSION_KEY, KIT_VERSION);
k->setValue(KIT_MCUTARGET_OS_KEY, static_cast<int>(mcuTarget->os()));
k->setValue(KIT_MCUTARGET_TOOCHAIN_KEY, mcuTarget->toolChainPackage()->toolChainName());
k->setAutoDetected(false);
k->makeSticky();
if (mcuTarget->toolChainPackage()->isDesktopToolchain())
k->setDeviceTypeForIcon(DEVICE_TYPE);
k->setValue(QtSupport::SuppliesQtQuickImportPath::id(), true);
k->setValue(QtSupport::KitQmlImportPath::id(), sdkPath.pathAppended("include/qul").toVariant());
k->setValue(QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(), true);
QSet<Id> irrelevant = {
SysRootKitAspect::id(),
QtSupport::SuppliesQtQuickImportPath::id(),
QtSupport::KitQmlImportPath::id(),
QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(),
};
if (!kitNeedsQtVersion())
irrelevant.insert(QtSupport::QtKitAspect::id());
k->setIrrelevantAspects(irrelevant);
}
void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems) void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems)
{ {
const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems); const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems);
@@ -567,7 +258,7 @@ void McuSupportOptions::setKitEnvironment(Kit *k,
processPackage(package); processPackage(package);
processPackage(qtForMCUsSdkPackage); processPackage(qtForMCUsSdkPackage);
if (kitNeedsQtVersion()) if (McuSupportOptions::kitsNeedQtVersion())
changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"}); changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"});
// Hack, this problem should be solved in lower layer // Hack, this problem should be solved in lower layer
@@ -666,7 +357,7 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth) if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH", config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
QString::number(mcuTarget->colorDepth()).toLatin1())); QString::number(mcuTarget->colorDepth()).toLatin1()));
if (kitNeedsQtVersion()) if (McuSupportOptions::kitsNeedQtVersion())
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}")); config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
CMakeConfigurationKitAspect::setConfiguration(k, config); CMakeConfigurationKitAspect::setConfiguration(k, config);
@@ -682,129 +373,11 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
static void setKitQtVersionOptions(Kit *k) static void setKitQtVersionOptions(Kit *k)
{ {
if (!kitNeedsQtVersion()) 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
} }
QString McuKitManager::kitName(const McuTarget *mcuTarget)
{
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
? QString::fromLatin1(" (%1)").arg(
tcPkg->toolChainName().toUpper())
: "";
const QString colorDepth = mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
: "";
const QString targetName = mcuTarget->platform().displayName.isEmpty()
? mcuTarget->platform().name
: mcuTarget->platform().displayName;
return QString::fromLatin1("Qt for MCUs %1.%2 - %3%4%5")
.arg(QString::number(mcuTarget->qulVersion().majorVersion()),
QString::number(mcuTarget->qulVersion().minorVersion()),
targetName,
colorDepth,
compilerName);
}
QList<Kit *> McuKitManager::existingKits(const McuTarget *mcuTarget)
{
using namespace Constants;
return Utils::filtered(KitManager::kits(), [mcuTarget](Kit *kit) {
return kit->value(KIT_MCUTARGET_KITVERSION_KEY) == KIT_VERSION
&& (!mcuTarget
|| (kit->value(KIT_MCUTARGET_VENDOR_KEY) == mcuTarget->platform().vendor
&& kit->value(KIT_MCUTARGET_MODEL_KEY) == mcuTarget->platform().name
&& kit->value(KIT_MCUTARGET_COLORDEPTH_KEY) == mcuTarget->colorDepth()
&& kit->value(KIT_MCUTARGET_OS_KEY).toInt()
== static_cast<int>(mcuTarget->os())
&& kit->value(KIT_MCUTARGET_TOOCHAIN_KEY)
== mcuTarget->toolChainPackage()->toolChainName()));
});
}
QList<Kit *> McuKitManager::matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> McuKitManager::upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return !kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> McuKitManager::kitsWithMismatchedDependencies(const McuTarget *mcuTarget)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget](Kit *kit) {
const auto environment = Utils::NameValueDictionary(
Utils::NameValueItem::toStringList(EnvironmentKitAspect::environmentChanges(kit)));
return Utils::anyOf(mcuTarget->packages(),
[&environment](const McuAbstractPackage *package) {
return !package->environmentVariableName().isEmpty()
&& environment.value(package->environmentVariableName())
!= package->path().toUserOutput();
});
});
}
QList<Kit *> McuKitManager::outdatedKits()
{
return Utils::filtered(KitManager::kits(), [](Kit *kit) {
return !kit->value(Constants::KIT_MCUTARGET_VENDOR_KEY).isNull()
&& kit->value(Constants::KIT_MCUTARGET_KITVERSION_KEY) != KIT_VERSION;
});
}
void McuKitManager::removeOutdatedKits()
{
for (auto kit : outdatedKits())
KitManager::deregisterKit(kit);
}
Kit *McuKitManager::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());
McuSupportOptions::setKitEnvironment(k, mcuTarget, qtForMCUsSdk);
setKitDependencies(k, mcuTarget, qtForMCUsSdk);
setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk->path());
setKitQtVersionOptions(k);
k->setup();
k->fix();
};
return KitManager::registerKit(init);
}
void printMessage(const QString &message, bool important)
{
const QString displayMessage = QCoreApplication::translate("QtForMCUs", "Qt for MCUs: %1")
.arg(message);
if (important)
Core::MessageManager::writeFlashing(displayMessage);
else
Core::MessageManager::writeSilently(displayMessage);
}
QVersionNumber McuKitManager::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) static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
{ {
for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) { for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) {
@@ -814,21 +387,7 @@ static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
return FilePath(); return FilePath();
} }
bool McuKitManager::kitIsUpToDate(const Kit *kit, McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades()
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return kitQulVersion(kit) == mcuTarget->qulVersion()
&& kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()).toUserOutput()
== qtForMCUsSdkPackage->path().toUserOutput();
}
void McuSupportOptions::deletePackagesAndTargets()
{
sdkRepository.deletePackagesAndTargets();
}
McuKitManager::UpgradeOption McuKitManager::askForKitUpgrades()
{ {
QMessageBox upgradePopup(Core::ICore::dialogParent()); QMessageBox upgradePopup(Core::ICore::dialogParent());
upgradePopup.setStandardButtons(QMessageBox::Cancel); upgradePopup.setStandardButtons(QMessageBox::Cancel);
@@ -841,87 +400,20 @@ McuKitManager::UpgradeOption McuKitManager::askForKitUpgrades()
upgradePopup.exec(); upgradePopup.exec();
if (upgradePopup.clickedButton() == keepButton) if (upgradePopup.clickedButton() == keepButton)
return UpgradeOption::Keep; return McuKitManager::UpgradeOption::Keep;
if (upgradePopup.clickedButton() == replaceButton) if (upgradePopup.clickedButton() == replaceButton)
return UpgradeOption::Replace; return McuKitManager::UpgradeOption::Replace;
return UpgradeOption::Ignore; return McuKitManager::UpgradeOption::Ignore;
} }
void McuKitManager::createAutomaticKits()
void McuSupportOptions::deletePackagesAndTargets()
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); sdkRepository.deletePackagesAndTargets();
const auto createKits = [qtForMCUsPackage]() {
if (qtForMCUsPackage->automaticKitCreationEnabled()) {
qtForMCUsPackage->updateStatus();
if (!qtForMCUsPackage->validStatus()) {
switch (qtForMCUsPackage->status()) {
case McuAbstractPackage::Status::ValidPathInvalidPackage: {
const QString displayPath
= FilePath::fromString(qtForMCUsPackage->detectionPath()).toUserOutput();
printMessage(tr("Path %1 exists, but does not contain %2.")
.arg(qtForMCUsPackage->path().toUserOutput(), displayPath),
true);
break;
}
case McuAbstractPackage::Status::InvalidPath: {
printMessage(tr("Path %1 does not exist. Add the path in Tools > Options > "
"Devices > MCU.")
.arg(qtForMCUsPackage->path().toUserOutput()),
true);
break;
}
case McuAbstractPackage::Status::EmptyPath: {
printMessage(tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath()),
true);
return;
}
default:
break;
}
return;
} }
if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) {
printMessage(tr("No CMake tool was detected. Add a CMake tool in Tools > Options > "
"Kits > CMake."),
true);
return;
}
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
bool needsUpgrade = false;
for (const auto &target : qAsConst(repo.mcuTargets)) {
// if kit already exists, skip
if (!matchingKits(target, qtForMCUsPackage).empty())
continue;
if (!upgradeableKits(target, qtForMCUsPackage).empty()) {
// if kit exists but wrong version/path
needsUpgrade = true;
} else {
// if no kits for this target, create
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
if (needsUpgrade)
McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade();
}
};
createKits();
delete qtForMCUsPackage;
}
void McuSupportOptions::checkUpgradeableKits() void McuSupportOptions::checkUpgradeableKits()
{ {
@@ -932,142 +424,14 @@ void McuSupportOptions::checkUpgradeableKits()
return !McuKitManager::upgradeableKits(target, this->qtForMCUsSdkPackage).empty() return !McuKitManager::upgradeableKits(target, this->qtForMCUsSdkPackage).empty()
&& McuKitManager::matchingKits(target, this->qtForMCUsSdkPackage).empty(); && McuKitManager::matchingKits(target, this->qtForMCUsSdkPackage).empty();
})) }))
McuKitManager::upgradeKitsByCreatingNewPackage(McuKitManager::askForKitUpgrades()); McuKitManager::upgradeKitsByCreatingNewPackage(askForKitUpgrades());
} }
void McuKitManager::upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption) bool McuSupportOptions::kitsNeedQtVersion()
{ {
if (upgradeOption == UpgradeOption::Ignore) // Only on Windows, Qt is linked into the distributed qul Desktop libs. Also, the host tools
return; // are missing the Qt runtime libraries on non-Windows.
return !HostOsInfo::isWindowsHost();
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
auto dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (!McuKitManager::matchingKits(target, qtForMCUsPackage).empty())
// already up-to-date
continue;
const auto kits = McuKitManager::upgradeableKits(target, qtForMCUsPackage);
if (!kits.empty()) {
if (upgradeOption == UpgradeOption::Replace) {
for (auto existingKit : kits)
KitManager::deregisterKit(existingKit);
}
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
void McuKitManager::upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk)
{
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path());
McuSupportOptions::setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
setKitDependencies(kit, mcuTarget, qtForMCUsSdk);
}
void McuKitManager::fixKitsDependencies()
{
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (target->isValid()) {
for (auto *kit : kitsWithMismatchedDependencies(target)) {
McuSupportOptions::updateKitEnvironment(kit, target);
}
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
/**
* @brief Fix/update existing kits if needed
*/
void McuKitManager::fixExistingKits()
{
for (Kit *kit : KitManager::kits()) {
if (!kit->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY))
continue;
if (kit->isAutoDetected()) {
kit->setAutoDetected(false);
}
// Check if the MCU kits are flagged as supplying a QtQuick import path, in order
// to tell the QMLJS code-model that it won't need to add a fall-back import
// path.
const auto bringsQtQuickImportPath = QtSupport::SuppliesQtQuickImportPath::id();
auto irrelevantAspects = kit->irrelevantAspects();
if (!irrelevantAspects.contains(bringsQtQuickImportPath)) {
irrelevantAspects.insert(bringsQtQuickImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(bringsQtQuickImportPath)) {
kit->setValue(bringsQtQuickImportPath, true);
}
// Check if the MCU kit supplies its import path.
const auto kitQmlImportPath = QtSupport::KitQmlImportPath::id();
if (!irrelevantAspects.contains(kitQmlImportPath)) {
irrelevantAspects.insert(kitQmlImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(kitQmlImportPath)) {
auto config = CMakeProjectManager::CMakeConfigurationKitAspect::configuration(kit);
for (const auto &cfgItem : qAsConst(config)) {
if (cfgItem.key == "QUL_GENERATORS") {
auto idx = cfgItem.value.indexOf("/lib/cmake/Qul");
auto qulDir = cfgItem.value.left(idx);
kit->setValue(kitQmlImportPath, QVariant(qulDir + "/include/qul"));
break;
}
}
}
// Check if the MCU kit has the flag for merged header/qml-import paths set.
const auto mergedPaths = QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id();
if (!irrelevantAspects.contains(mergedPaths)) {
irrelevantAspects.insert(mergedPaths);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->value(mergedPaths, false).toBool()) {
kit->setValue(mergedPaths, true);
}
}
// Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->validStatus()) {
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets))
for (auto kit : existingKits(target)) {
if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) {
setKitDependencies(kit, target, qtForMCUsPackage);
}
}
repo.deletePackagesAndTargets();
}
delete qtForMCUsPackage;
} }
} // namespace Internal } // namespace Internal

View File

@@ -27,8 +27,8 @@
#include <utils/environmentfwd.h> #include <utils/environmentfwd.h>
#include "mcusupport_global.h" #include "mcusupport_global.h"
#include "mcukitmanager.h"
#include <QCoreApplication>
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
#include <QVersionNumber> #include <QVersionNumber>
@@ -51,49 +51,7 @@ namespace Internal {
class McuAbstractPackage; class McuAbstractPackage;
class McuToolChainPackage; class McuToolChainPackage;
class McuTarget;
void printMessage(const QString &message, bool important);
class McuTarget : public QObject
{
Q_OBJECT
public:
enum class OS { Desktop, BareMetal, FreeRTOS };
struct Platform
{
QString name;
QString displayName;
QString vendor;
};
enum { UnspecifiedColorDepth = -1 };
McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth = UnspecifiedColorDepth);
const QVersionNumber &qulVersion() const;
const QVector<McuAbstractPackage *> &packages() const;
const McuToolChainPackage *toolChainPackage() const;
const Platform &platform() const;
OS os() const;
int colorDepth() const;
bool isValid() const;
void printPackageProblems() const;
private:
const QVersionNumber m_qulVersion;
const Platform m_platform;
const OS m_os;
const QVector<McuAbstractPackage *> m_packages;
const McuToolChainPackage *m_toolChainPackage;
const int m_colorDepth;
}; // class McuTarget
class McuSdkRepository class McuSdkRepository
{ {
@@ -122,6 +80,7 @@ public:
static void updateKitEnvironment(ProjectExplorer::Kit *, const McuTarget *); static void updateKitEnvironment(ProjectExplorer::Kit *, const McuTarget *);
static void remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &); static void remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &);
static Utils::FilePath qulDirFromSettings(); static Utils::FilePath qulDirFromSettings();
static McuKitManager::UpgradeOption askForKitUpgrades();
static void registerQchFiles(); static void registerQchFiles();
static void registerExamples(); static void registerExamples();
@@ -130,6 +89,8 @@ public:
void checkUpgradeableKits(); void checkUpgradeableKits();
void populatePackagesAndTargets(); void populatePackagesAndTargets();
static bool kitsNeedQtVersion();
private: private:
void deletePackagesAndTargets(); void deletePackagesAndTargets();
@@ -137,47 +98,6 @@ signals:
void packagesChanged(); void packagesChanged();
}; };
class McuKitManager
{
Q_DECLARE_TR_FUNCTIONS(McuSupport::Internal::McuKitManager)
public:
enum class UpgradeOption {
Ignore,
Keep,
Replace
};
// Creating kits:
static ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
static void createAutomaticKits();
// Querying the kits:
static QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
static QList<ProjectExplorer::Kit *> upgradeableKits(
const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
static QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
// Upgrading kits:
static UpgradeOption askForKitUpgrades();
static void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption);
static void upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
// Fixing kits:
static void fixKitsDependencies();
static void fixExistingKits();
// Outdated kits:
static QList<ProjectExplorer::Kit *> outdatedKits();
static void removeOutdatedKits();
// Querying kits:
static QString kitName(const McuTarget* mcuTarget);
static QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
static bool kitIsUpToDate(const ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
};
} // namespace Internal } // namespace Internal
} // namespace McuSupport } // namespace McuSupport

View File

@@ -25,9 +25,11 @@
#include "mcusupportoptionspage.h" #include "mcusupportoptionspage.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcukitmanager.h"
#include <cmakeprojectmanager/cmakeprojectconstants.h> #include <cmakeprojectmanager/cmakeprojectconstants.h>
#include <cmakeprojectmanager/cmaketoolmanager.h> #include <cmakeprojectmanager/cmaketoolmanager.h>

View File

@@ -28,6 +28,7 @@
#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"
@@ -38,6 +39,7 @@
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/jsonwizard/jsonwizardfactory.h> #include <projectexplorer/jsonwizard/jsonwizardfactory.h>
@@ -53,6 +55,16 @@ using namespace ProjectExplorer;
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
void printMessage(const QString &message, bool important)
{
const QString displayMessage = QCoreApplication::translate("QtForMCUs", "Qt for MCUs: %1")
.arg(message);
if (important)
Core::MessageManager::writeFlashing(displayMessage);
else
Core::MessageManager::writeSilently(displayMessage);
}
class McuSupportPluginPrivate class McuSupportPluginPrivate
{ {
public: public:

View File

@@ -31,6 +31,8 @@
namespace McuSupport::Internal { namespace McuSupport::Internal {
void printMessage(const QString &message, bool important);
class McuSupportPlugin final : public ExtensionSystem::IPlugin class McuSupportPlugin final : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT

View File

@@ -25,10 +25,13 @@
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcukitmanager.h"
#include "mcusupportversiondetection.h" #include "mcusupportversiondetection.h"
#include "mcutargetdescription.h" #include "mcutargetdescription.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h> #include <baremetal/baremetalconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>

View File

@@ -0,0 +1,290 @@
/****************************************************************************
**
** Copyright (C) 2022 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 "mcutarget.h"
#include "mcupackage.h"
#include "mcukitmanager.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace McuSupport::Internal {
static ToolChain *msvcToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor
|| abi.osFlavor() == Abi::WindowsMsvc2019Flavor)
&& abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64
&& t->language() == language;
});
return toolChain;
}
static ToolChain *gccToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture
&& abi.wordWidth() == 64 && t->language() == language;
});
return toolChain;
}
static ToolChain *armGccToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) {
return t->compilerCommand() == path && t->language() == language;
});
if (!toolChain) {
ToolChainFactory *gccFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
});
if (gccFactory) {
const QList<ToolChain *> detected = gccFactory->detectForImport({path, language});
if (!detected.isEmpty()) {
toolChain = detected.first();
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("Arm GCC");
ToolChainManager::registerToolChain(toolChain);
}
}
}
return toolChain;
}
static ToolChain *iarToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID
&& t->language() == language;
});
if (!toolChain) {
ToolChainFactory *iarFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
});
if (iarFactory) {
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
if (detected.isEmpty())
detected = iarFactory->detectForImport({path, language});
for (auto tc : detected) {
if (tc->language() == language) {
toolChain = tc;
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("IAREW");
ToolChainManager::registerToolChain(toolChain);
}
}
}
}
return toolChain;
}
ToolChain *McuToolChainPackage::toolChain(Id language) const
{
switch (m_type) {
case Type::MSVC:
return msvcToolChain(language);
case Type::GCC:
return gccToolChain(language);
case Type::IAR: {
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
return iarToolChain(compiler, language);
}
case Type::ArmGcc:
case Type::KEIL:
case Type::GHS:
case Type::GHSArm:
case Type::Unsupported: {
const QLatin1String compilerName(
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
const QString comp = QLatin1String(m_type == Type::ArmGcc ? "/bin/arm-none-eabi-%1"
: "/bar/foo-keil-%1")
.arg(compilerName);
const FilePath compiler = path().pathAppended(comp).withExecutableSuffix();
return armGccToolChain(compiler, language);
}
default:
Q_UNREACHABLE();
}
}
QString McuToolChainPackage::toolChainName() const
{
switch (m_type) {
case Type::ArmGcc:
return QLatin1String("armgcc");
case Type::IAR:
return QLatin1String("iar");
case Type::KEIL:
return QLatin1String("keil");
case Type::GHS:
return QLatin1String("ghs");
case Type::GHSArm:
return QLatin1String("ghs-arm");
default:
return QLatin1String("unsupported");
}
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
}
QVariant McuToolChainPackage::debuggerId() const
{
using namespace Debugger;
QString sub, displayName;
DebuggerEngineType engineType;
switch (m_type) {
case Type::ArmGcc: {
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
displayName = McuPackage::tr("Arm GDB at %1");
engineType = Debugger::GdbEngineType;
break;
}
case Type::IAR: {
sub = QString::fromLatin1("../common/bin/CSpyBat");
displayName = QLatin1String("CSpy");
engineType = Debugger::NoEngineType; // support for IAR missing
break;
}
case Type::KEIL: {
sub = QString::fromLatin1("UV4/UV4");
displayName = QLatin1String("KEIL uVision Debugger");
engineType = Debugger::UvscEngineType;
break;
}
default:
return QVariant();
}
const FilePath command = path().pathAppended(sub).withExecutableSuffix();
if (const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command)) {
return debugger->id();
}
DebuggerItem newDebugger;
newDebugger.setCommand(command);
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
newDebugger.setEngineType(engineType);
return DebuggerItemManager::registerDebugger(newDebugger);
}
McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth)
: m_qulVersion(qulVersion)
, m_platform(platform)
, m_os(os)
, m_packages(packages)
, m_toolChainPackage(toolChainPackage)
, m_colorDepth(colorDepth)
{}
const QVector<McuAbstractPackage *> &McuTarget::packages() const
{
return m_packages;
}
const McuToolChainPackage *McuTarget::toolChainPackage() const
{
return m_toolChainPackage;
}
McuTarget::OS McuTarget::os() const
{
return m_os;
}
const McuTarget::Platform &McuTarget::platform() const
{
return m_platform;
}
bool McuTarget::isValid() const
{
return Utils::allOf(packages(), [](McuAbstractPackage *package) {
package->updateStatus();
return package->validStatus();
});
}
void McuTarget::printPackageProblems() const
{
for (auto package : packages()) {
package->updateStatus();
if (!package->validStatus())
printMessage(tr("Error creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this),
package->label(),
package->statusText()),
true);
if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion)
printMessage(tr("Warning creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this),
package->label(),
package->statusText()),
false);
}
}
const QVersionNumber &McuTarget::qulVersion() const
{
return m_qulVersion;
}
int McuTarget::colorDepth() const
{
return m_colorDepth;
}
} // namespace McuSupport::Internal

View File

@@ -0,0 +1,89 @@
/****************************************************************************
**
** Copyright (C) 2022 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 <QObject>
#include <QVersionNumber>
namespace ProjectExplorer {
class ToolChain;
}
namespace Utils {
class PathChooser;
class InfoLabel;
} // namespace Utils
namespace McuSupport {
namespace Internal {
class McuAbstractPackage;
class McuToolChainPackage;
class McuTarget : public QObject
{
Q_OBJECT
public:
enum class OS { Desktop, BareMetal, FreeRTOS };
struct Platform
{
QString name;
QString displayName;
QString vendor;
};
enum { UnspecifiedColorDepth = -1 };
McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth = UnspecifiedColorDepth);
const QVersionNumber &qulVersion() const;
const QVector<McuAbstractPackage *> &packages() const;
const McuToolChainPackage *toolChainPackage() const;
const Platform &platform() const;
OS os() const;
int colorDepth() const;
bool isValid() const;
void printPackageProblems() const;
private:
const QVersionNumber m_qulVersion;
const Platform m_platform;
const OS m_os;
const QVector<McuAbstractPackage *> m_packages;
const McuToolChainPackage *m_toolChainPackage;
const int m_colorDepth;
}; // class McuTarget
} // namespace Internal
} // namespace McuSupport

View File

@@ -25,6 +25,7 @@
#include "unittest.h" #include "unittest.h"
#include "mcutargetdescription.h" #include "mcutargetdescription.h"
#include "mcukitmanager.h"
#include "nxp_1064_json.h" #include "nxp_1064_json.h"
#include "utils/filepath.h" #include "utils/filepath.h"
#include <cmakeprojectmanager/cmakeconfigitem.h> #include <cmakeprojectmanager/cmakeconfigitem.h>

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include "mcupackage.h" #include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportplugin.h" #include "mcusupportplugin.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"