forked from qt-creator/qt-creator
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:
@@ -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
|
||||||
|
596
src/plugins/mcusupport/mcukitmanager.cpp
Normal file
596
src/plugins/mcusupport/mcukitmanager.cpp
Normal 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
|
86
src/plugins/mcusupport/mcukitmanager.h
Normal file
86
src/plugins/mcusupport/mcukitmanager.h
Normal 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
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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",
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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>
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
@@ -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>
|
||||||
|
290
src/plugins/mcusupport/mcutarget.cpp
Normal file
290
src/plugins/mcusupport/mcutarget.cpp
Normal 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
|
89
src/plugins/mcusupport/mcutarget.h
Normal file
89
src/plugins/mcusupport/mcutarget.h
Normal 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
|
@@ -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>
|
||||||
|
@@ -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"
|
||||||
|
Reference in New Issue
Block a user