McuSupport: support for SDK 2.0

This is a quick fix for the current situation. Proper
support will need a rewrite of part of the plugin code.

QtQuickUltralite SDK 1.x relies on environment variables
for the dependencies. SDK 2.x uses CMake variables for that purpose.
Some of the variables have been renamed, others grouped together.

Here a mapping between those is hardcoded as an urgent solution.
A proper implementation should make the plugin independent of
the existence or lack of specific environment variables. Also,
all the hardcoded information needs to be moved to the json kit
files in the SDK. Otherwise, compatibility breaks between versions
every time the built-in assumptions relating to that information change.

Task-number: UL-4396
Change-Id: I7f40a694a773881f20b29bae9d02c7c1c8bd747b
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Christiaan Janssen
2021-09-29 17:23:11 +02:00
parent 9edecd1c94
commit 0eeb6c6e5e
11 changed files with 375 additions and 143 deletions

View File

@@ -12,4 +12,5 @@ add_qtc_plugin(McuSupport
mcusupportsdk.cpp mcusupportsdk.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h
mcusupportversiondetection.cpp mcusupportversiondetection.h
mcusupportcmakemapper.cpp mcusupportcmakemapper.h
)

View File

@@ -13,7 +13,8 @@ HEADERS += \
mcusupportplugin.h \
mcusupportsdk.h \
mcusupportrunconfiguration.h \
mcusupportversiondetection.h
mcusupportversiondetection.h \
mcusupportcmakemapper.h
SOURCES += \
mcusupportdevice.cpp \
@@ -22,7 +23,8 @@ SOURCES += \
mcusupportplugin.cpp \
mcusupportsdk.cpp \
mcusupportrunconfiguration.cpp \
mcusupportversiondetection.cpp
mcusupportversiondetection.cpp \
mcusupportcmakemapper.cpp
RESOURCES += \
mcusupport.qrc

View File

@@ -32,5 +32,7 @@ QtcPlugin {
"mcusupportrunconfiguration.h",
"mcusupportversiondetection.cpp",
"mcusupportversiondetection.h",
"mcusupportcmakemapper.h",
"mcusupportcmakemapper.cpp"
]
}

View File

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

View File

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

View File

@@ -27,6 +27,7 @@
#include "mcusupportoptions.h"
#include "mcusupportsdk.h"
#include "mcusupportplugin.h"
#include "mcusupportcmakemapper.h"
#include <baremetal/baremetalconstants.h>
#include <cmakeprojectmanager/cmaketoolmanager.h>
@@ -70,7 +71,7 @@ using namespace Utils;
namespace McuSupport {
namespace Internal {
static const int KIT_VERSION = 8; // Bumps up whenever details in Kit creation change
static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change
static FilePath packagePathFromSettings(const QString &settingsKey,
QSettings::Scope scope = QSettings::UserScope,
@@ -99,6 +100,22 @@ static bool kitNeedsQtVersion()
return !HostOsInfo::isWindowsHost();
}
static void remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems)
{
using namespace CMakeProjectManager;
const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems);
const auto cmakeVarNames = Utils::transform(cmakeVars, &CMakeConfigItem::key);
// First filter out all Qul2.x CMake vars
auto config = Utils::filtered(CMakeConfigurationKitAspect::configuration(kit),
[&](const auto &configItem) {
return !cmakeVarNames.contains(configItem.key);
});
// Then append them with new values
config.append(cmakeVars);
CMakeConfigurationKitAspect::setConfiguration(kit, config);
}
McuPackage::McuPackage(const QString &label, const FilePath &defaultPath,
const QString &detectionPath, const QString &settingsKey,
const McuPackageVersionDetector *versionDetector)
@@ -231,7 +248,7 @@ bool McuPackage::writeToSettings() const
const FilePath savedPath = packagePathFromSettings(m_settingsKey, QSettings::UserScope, m_defaultPath);
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/' +
QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey;
Core::ICore::settings()->setValueWithDefault(key, m_path, m_defaultPath);
Core::ICore::settings()->setValueWithDefault(key, m_path.toString(), m_defaultPath.toString());
return savedPath != m_path;
}
@@ -573,6 +590,14 @@ void McuTarget::setColorDepth(int colorDepth)
m_colorDepth = colorDepth;
}
void McuSdkRepository::deletePackagesAndTargets()
{
qDeleteAll(packages);
packages.clear();
qDeleteAll(mcuTargets);
mcuTargets.clear();
}
McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent)
, qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage())
@@ -635,14 +660,6 @@ void McuSupportOptions::registerExamples()
}
}
void McuSupportOptions::deletePackagesAndTargets()
{
qDeleteAll(packages);
packages.clear();
qDeleteAll(mcuTargets);
mcuTargets.clear();
}
const QVersionNumber &McuSupportOptions::minimalQulVersion()
{
static const QVersionNumber v({1, 3});
@@ -654,8 +671,8 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
deletePackagesAndTargets();
qtForMCUsSdkPackage->updateStatus();
if (qtForMCUsSdkPackage->validStatus())
Sdk::targetsAndPackages(dir, &packages, &mcuTargets);
for (auto package : qAsConst(packages))
Sdk::targetsAndPackages(dir, &sdkRepository);
for (const auto &package : qAsConst(sdkRepository.packages))
connect(package, &McuPackage::changed, this, &McuSupportOptions::changed);
emit changed();
@@ -736,6 +753,11 @@ static void setKitDevice(Kit *k, const McuTarget* mcuTarget)
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
}
static bool expectsCmakeVars(const McuTarget *mcuTarget)
{
return mcuTarget->qulVersion() >= QVersionNumber{2,0};
}
static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget,
const McuPackage *qtForMCUsSdkPackage)
{
@@ -770,6 +792,11 @@ static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget,
if (kitNeedsQtVersion())
changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"});
// Hack, this problem should be solved in lower layer
if (expectsCmakeVars(mcuTarget)) {
remapQul2xCmakeVars(k, changes);
}
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
@@ -812,6 +839,11 @@ static void updateKitEnvironment(Kit *k, const McuTarget *mcuTarget)
}
}
// Hack, this problem should be solved in lower layer
if (expectsCmakeVars(mcuTarget)) {
remapQul2xCmakeVars(k, changes);
}
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
@@ -1015,6 +1047,11 @@ bool McuSupportOptions::kitUpToDate(const Kit *kit, const McuTarget *mcuTarget,
kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()) == qtForMCUsSdkPackage->path();
}
void McuSupportOptions::deletePackagesAndTargets()
{
sdkRepository.deletePackagesAndTargets();
}
McuSupportOptions::UpgradeOption McuSupportOptions::askForKitUpgrades()
{
QMessageBox upgradePopup(Core::ICore::dialogParent());
@@ -1076,12 +1113,11 @@ void McuSupportOptions::createAutomaticKits()
}
FilePath dir = qtForMCUsPackage->path();
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
Sdk::targetsAndPackages(dir, &packages, &mcuTargets);
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
bool needsUpgrade = false;
for (auto target: qAsConst(mcuTargets)) {
for (const auto &target: qAsConst(repo.mcuTargets)) {
// if kit already exists, skip
if (!matchingKits(target, qtForMCUsPackage).empty())
continue;
@@ -1096,8 +1132,7 @@ void McuSupportOptions::createAutomaticKits()
}
}
qDeleteAll(packages);
qDeleteAll(mcuTargets);
repo.deletePackagesAndTargets();
if (needsUpgrade)
McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade();
@@ -1110,10 +1145,10 @@ void McuSupportOptions::createAutomaticKits()
void McuSupportOptions::checkUpgradeableKits()
{
if (!qtForMCUsSdkPackage->validStatus() || mcuTargets.length() == 0)
if (!qtForMCUsSdkPackage->validStatus() || sdkRepository.mcuTargets.length() == 0)
return;
if (Utils::anyOf(mcuTargets, [this](const McuTarget *target) {
if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) {
return !upgradeableKits(target, this->qtForMCUsSdkPackage).empty() &&
matchingKits(target, this->qtForMCUsSdkPackage).empty();
}))
@@ -1128,11 +1163,10 @@ void McuSupportOptions::upgradeKits(UpgradeOption upgradeOption)
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
auto dir = qtForMCUsPackage->path();
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
Sdk::targetsAndPackages(dir, &packages, &mcuTargets);
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (auto target: qAsConst(mcuTargets)) {
for (const auto &target: qAsConst(repo.mcuTargets)) {
if (!matchingKits(target, qtForMCUsPackage).empty())
// already up-to-date
continue;
@@ -1149,8 +1183,7 @@ void McuSupportOptions::upgradeKits(UpgradeOption upgradeOption)
}
}
qDeleteAll(packages);
qDeleteAll(mcuTargets);
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
@@ -1166,10 +1199,9 @@ void McuSupportOptions::fixKitsDependencies()
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
FilePath dir = qtForMCUsPackage->path();
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
Sdk::targetsAndPackages(dir, &packages, &mcuTargets);
for (auto target: qAsConst(mcuTargets)) {
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target: qAsConst(repo.mcuTargets)) {
if (target->isValid()) {
for (auto kit : kitsWithMismatchedDependencies(target)) {
updateKitEnvironment(kit, target);
@@ -1177,8 +1209,7 @@ void McuSupportOptions::fixKitsDependencies()
}
}
qDeleteAll(packages);
qDeleteAll(mcuTargets);
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
@@ -1242,18 +1273,16 @@ void McuSupportOptions::fixExistingKits()
qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->validStatus()) {
FilePath dir = qtForMCUsPackage->path();
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
Sdk::targetsAndPackages(dir, &packages, &mcuTargets);
for (auto target: qAsConst(mcuTargets))
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);
}
}
qDeleteAll(packages);
qDeleteAll(mcuTargets);
repo.deletePackagesAndTargets();
}
delete qtForMCUsPackage;
}

View File

@@ -200,6 +200,14 @@ private:
int m_colorDepth = -1;
};
struct McuSdkRepository
{
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
void deletePackagesAndTargets();
};
class McuSupportOptions : public QObject
{
Q_OBJECT
@@ -214,9 +222,8 @@ public:
McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override;
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
McuPackage *qtForMCUsSdkPackage = nullptr;
McuSdkRepository sdkRepository;
void setQulDir(const Utils::FilePath &dir);
static Utils::FilePath qulDirFromSettings();

View File

@@ -190,7 +190,7 @@ void McuSupportOptionsWidget::updateStatus()
m_mcuTargetsGroupBox->setVisible(ready);
m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty());
m_kitCreationGroupBox->setVisible(ready);
m_mcuTargetsInfoLabel->setVisible(valid && m_options.mcuTargets.isEmpty());
m_mcuTargetsInfoLabel->setVisible(valid && m_options.sdkRepository.mcuTargets.isEmpty());
if (m_mcuTargetsInfoLabel->isVisible()) {
m_mcuTargetsInfoLabel->setType(Utils::InfoLabel::NotOk);
const Utils::FilePath sdkPath = m_options.qtForMCUsSdkPackage->basePath();
@@ -261,7 +261,7 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
row.fieldItem->widget()->hide();
}
for (auto package : qAsConst(m_options.packages)) {
for (auto package : qAsConst(m_options.sdkRepository.packages)) {
QWidget *packageWidget = package->widget();
if (!mcuTarget->packages().contains(package))
continue;
@@ -275,9 +275,9 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
McuTarget *McuSupportOptionsWidget::currentMcuTarget() const
{
const int mcuTargetIndex = m_mcuTargetsComboBox->currentIndex();
return (mcuTargetIndex == -1 || m_options.mcuTargets.isEmpty())
return (mcuTargetIndex == -1 || m_options.sdkRepository.mcuTargets.isEmpty())
? nullptr
: m_options.mcuTargets.at(mcuTargetIndex);
: m_options.sdkRepository.mcuTargets.at(mcuTargetIndex);
}
void McuSupportOptionsWidget::showEvent(QShowEvent *event)
@@ -292,7 +292,7 @@ void McuSupportOptionsWidget::apply()
m_options.qtForMCUsSdkPackage->writeGeneralSettings();
pathsChanged |= m_options.qtForMCUsSdkPackage->writeToSettings();
for (auto package : qAsConst(m_options.packages))
for (auto package : qAsConst(m_options.sdkRepository.packages))
pathsChanged |= package->writeToSettings();
if (pathsChanged) {
@@ -306,7 +306,7 @@ void McuSupportOptionsWidget::populateMcuTargetsComboBox()
m_options.populatePackagesAndTargets();
m_mcuTargetsComboBox->clear();
m_mcuTargetsComboBox->addItems(
Utils::transform<QStringList>(m_options.mcuTargets, [](McuTarget *t) {
Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets, [](McuTarget *t) {
return McuSupportOptions::kitName(t);
}));
updateStatus();

View File

@@ -331,19 +331,28 @@ struct McuTargetDescription
};
QString qulVersion;
QString platform;
QString platformName;
QString platformVendor;
QString compatVersion;
struct {
QString id;
QString name;
QString vendor;
QVector<int> colorDepths;
QString toolchainId;
QVector<QString> toolchainVersions;
QString boardSdkEnvVar;
QString boardSdkName;
QString boardSdkDefaultPath;
QVector<QString> boardSdkVersions;
QString freeRTOSEnvVar;
QString freeRTOSBoardSdkSubDir;
TargetType type;
} platform;
struct {
QString id;
QVector<QString> versions;
} toolchain;
struct {
QString name;
QString defaultPath;
QString envVar;
QVector<QString> versions;
} boardSdk;
struct {
QString envVar;
QString boardSdkSubDir;
} freeRTOS;
};
static McuPackageVersionDetector* generatePackageVersionDetector(QString envVar)
@@ -373,29 +382,29 @@ static McuPackage *createBoardSdkPackage(const McuTargetDescription& desc)
auto sdkName = postfixPos > 0 ? envVar.left(postfixPos) : envVar;
return QString::fromLatin1("MCU SDK (%1)").arg(sdkName);
};
const QString sdkName = desc.boardSdkName.isEmpty() ? generateSdkName(desc.boardSdkEnvVar) : desc.boardSdkName;
const QString sdkName = desc.boardSdk.name.isEmpty() ? generateSdkName(desc.boardSdk.envVar) : desc.boardSdk.name;
const FilePath defaultPath = [&] {
const auto envVar = desc.boardSdkEnvVar.toLatin1();
const auto envVar = desc.boardSdk.envVar.toLatin1();
if (qEnvironmentVariableIsSet(envVar))
return FilePath::fromUserInput(qEnvironmentVariable(envVar));
if (!desc.boardSdkDefaultPath.isEmpty()) {
FilePath defaultPath = FilePath::fromUserInput(QDir::rootPath() + desc.boardSdkDefaultPath);
if (!desc.boardSdk.defaultPath.isEmpty()) {
FilePath defaultPath = FilePath::fromUserInput(QDir::rootPath() + desc.boardSdk.defaultPath);
if (defaultPath.exists())
return defaultPath;
}
return FileUtils::homePath();
}();
const auto versionDetector = generatePackageVersionDetector(desc.boardSdkEnvVar);
const auto versionDetector = generatePackageVersionDetector(desc.boardSdk.envVar);
auto result = new McuPackage(
sdkName,
defaultPath,
{},
desc.boardSdkEnvVar,
desc.boardSdk.envVar,
versionDetector);
result->setEnvironmentVariableName(desc.boardSdkEnvVar);
result->setEnvironmentVariableName(desc.boardSdk.envVar);
return result;
}
@@ -434,7 +443,7 @@ struct McuTargetFactory
{
auto qulVersion = QVersionNumber::fromString(description.qulVersion);
if (qulVersion <= QVersionNumber({1,3})) {
if (description.type == McuTargetDescription::TargetType::Desktop)
if (description.platform.type == McuTargetDescription::TargetType::Desktop)
return createDesktopTargetsLegacy(description);
// There was a platform backends related refactoring in Qul 1.4
@@ -459,44 +468,44 @@ protected:
QVector<McuTarget *> createMcuTargetsLegacy(const McuTargetDescription &desc)
{
QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id);
if (!tcPkg)
tcPkg = createUnsupportedToolChainPackage();
for (auto os : {McuTarget::OS::BareMetal, McuTarget::OS::FreeRTOS}) {
for (int colorDepth : desc.colorDepths) {
for (int colorDepth : desc.platform.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs = { tcPkg };
if (vendorPkgs.contains(desc.platformVendor))
required3rdPartyPkgs.push_back(vendorPkgs.value(desc.platformVendor));
if (vendorPkgs.contains(desc.platform.vendor))
required3rdPartyPkgs.push_back(vendorPkgs.value(desc.platform.vendor));
FilePath boardSdkDefaultPath;
if (!desc.boardSdkEnvVar.isEmpty()) {
if (!boardSdkPkgs.contains(desc.boardSdkEnvVar)) {
auto boardSdkPkg = desc.boardSdkEnvVar != "RGL_DIR"
if (!desc.boardSdk.envVar.isEmpty()) {
if (!boardSdkPkgs.contains(desc.boardSdk.envVar)) {
auto boardSdkPkg = desc.boardSdk.envVar != "RGL_DIR"
? createBoardSdkPackage(desc)
: createRGLPackage();
boardSdkPkgs.insert(desc.boardSdkEnvVar, boardSdkPkg);
boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg);
}
auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdkEnvVar);
auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdk.envVar);
boardSdkDefaultPath = boardSdkPkg->defaultPath();
required3rdPartyPkgs.append(boardSdkPkg);
}
if (os == McuTarget::OS::FreeRTOS) {
if (desc.freeRTOSEnvVar.isEmpty()) {
if (desc.freeRTOS.envVar.isEmpty()) {
continue;
} else {
if (!freeRTOSPkgs.contains(desc.freeRTOSEnvVar)) {
freeRTOSPkgs.insert(desc.freeRTOSEnvVar, createFreeRTOSSourcesPackage(
desc.freeRTOSEnvVar, boardSdkDefaultPath,
desc.freeRTOSBoardSdkSubDir));
if (!freeRTOSPkgs.contains(desc.freeRTOS.envVar)) {
freeRTOSPkgs.insert(desc.freeRTOS.envVar, createFreeRTOSSourcesPackage(
desc.freeRTOS.envVar, boardSdkDefaultPath,
desc.freeRTOS.boardSdkSubDir));
}
required3rdPartyPkgs.append(freeRTOSPkgs.value(desc.freeRTOSEnvVar));
required3rdPartyPkgs.append(freeRTOSPkgs.value(desc.freeRTOS.envVar));
}
}
const auto platform = McuTarget::Platform{ desc.platform, desc.platformName, desc.platformVendor };
const auto platform = McuTarget::Platform{ desc.platform.id, desc.platform.name, desc.platform.vendor };
auto mcuTarget = new McuTarget(QVersionNumber::fromString(desc.qulVersion),
platform, os, required3rdPartyPkgs, tcPkg);
if (desc.colorDepths.count() > 1)
if (desc.platform.colorDepths.count() > 1)
mcuTarget->setColorDepth(colorDepth);
mcuTargets.append(mcuTarget);
}
@@ -506,10 +515,10 @@ protected:
QVector<McuTarget *> createDesktopTargetsLegacy(const McuTargetDescription& desc)
{
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id);
if (!tcPkg)
tcPkg = createUnsupportedToolChainPackage();
const auto platform = McuTarget::Platform{ desc.platform, desc.platformName, desc.platformVendor };
const auto platform = McuTarget::Platform{ desc.platform.id, desc.platform.name, desc.platform.vendor };
auto desktopTarget = new McuTarget(QVersionNumber::fromString(desc.qulVersion),
platform, McuTarget::OS::Desktop, {}, tcPkg);
return { desktopTarget };
@@ -519,21 +528,21 @@ protected:
{
// OS deduction
const auto os = [&] {
if (desc.type == McuTargetDescription::TargetType::Desktop)
if (desc.platform.type == McuTargetDescription::TargetType::Desktop)
return McuTarget::OS::Desktop;
else if (!desc.freeRTOSEnvVar.isEmpty())
else if (!desc.freeRTOS.envVar.isEmpty())
return McuTarget::OS::FreeRTOS;
return McuTarget::OS::BareMetal;
}();
QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id);
if (tcPkg) {
if (QVersionNumber::fromString(desc.qulVersion) >= QVersionNumber({1,8}))
tcPkg->setVersions(desc.toolchainVersions);
tcPkg->setVersions(desc.toolchain.versions);
} else
tcPkg = createUnsupportedToolChainPackage();
for (int colorDepth : desc.colorDepths) {
for (int colorDepth : desc.platform.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs;
// Desktop toolchains don't need any additional settings
if (tcPkg
@@ -542,34 +551,34 @@ protected:
required3rdPartyPkgs.append(tcPkg);
// Add setting specific to platform IDE
if (vendorPkgs.contains(desc.platformVendor))
required3rdPartyPkgs.push_back(vendorPkgs.value(desc.platformVendor));
if (vendorPkgs.contains(desc.platform.vendor))
required3rdPartyPkgs.push_back(vendorPkgs.value(desc.platform.vendor));
// Board SDK specific settings
FilePath boardSdkDefaultPath;
if (!desc.boardSdkEnvVar.isEmpty()) {
if (!boardSdkPkgs.contains(desc.boardSdkEnvVar)) {
if (!desc.boardSdk.envVar.isEmpty()) {
if (!boardSdkPkgs.contains(desc.boardSdk.envVar)) {
auto boardSdkPkg = createBoardSdkPackage(desc);
boardSdkPkgs.insert(desc.boardSdkEnvVar, boardSdkPkg);
boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg);
}
auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdkEnvVar);
auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdk.envVar);
if (QVersionNumber::fromString(desc.qulVersion) >= QVersionNumber({1,8}))
boardSdkPkg->setVersions(desc.boardSdkVersions);
boardSdkPkg->setVersions(desc.boardSdk.versions);
boardSdkDefaultPath = boardSdkPkg->defaultPath();
required3rdPartyPkgs.append(boardSdkPkg);
}
// Free RTOS specific settings
if (!desc.freeRTOSEnvVar.isEmpty()) {
if (!freeRTOSPkgs.contains(desc.freeRTOSEnvVar)) {
freeRTOSPkgs.insert(desc.freeRTOSEnvVar, createFreeRTOSSourcesPackage(
desc.freeRTOSEnvVar, boardSdkDefaultPath,
desc.freeRTOSBoardSdkSubDir));
if (!desc.freeRTOS.envVar.isEmpty()) {
if (!freeRTOSPkgs.contains(desc.freeRTOS.envVar)) {
freeRTOSPkgs.insert(desc.freeRTOS.envVar, createFreeRTOSSourcesPackage(
desc.freeRTOS.envVar, boardSdkDefaultPath,
desc.freeRTOS.boardSdkSubDir));
}
required3rdPartyPkgs.append(freeRTOSPkgs.value(desc.freeRTOSEnvVar));
required3rdPartyPkgs.append(freeRTOSPkgs.value(desc.freeRTOS.envVar));
}
const auto platform = McuTarget::Platform{ desc.platform, desc.platformName, desc.platformVendor };
const auto platform = McuTarget::Platform{ desc.platform.id, desc.platform.name, desc.platform.vendor };
auto mcuTarget = new McuTarget(QVersionNumber::fromString(desc.qulVersion),
platform, os, required3rdPartyPkgs, tcPkg);
mcuTarget->setColorDepth(colorDepth);
@@ -634,17 +643,20 @@ static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir)
return kitsDir.entryInfoList();
}
static McuTargetDescription parseDescriptionJson(const QByteArray &data)
static QString extractQulVersion(const QByteArray &data)
{
const QJsonDocument document = QJsonDocument::fromJson(data);
const QJsonObject target = document.object();
return target.value("qulVersion").toString();
}
static McuTargetDescription parseDescriptionJsonCommon(const QString &qulVersion, const QJsonObject &target)
{
const QString compatVersion = target.value("compatVersion").toString();
const QJsonObject toolchain = target.value("toolchain").toObject();
const QJsonObject boardSdk = target.value("boardSdk").toObject();
const QJsonObject freeRTOS = target.value("freeRTOS").toObject();
const QVariantList colorDepths = target.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int> >(
colorDepths, [&](const QVariant &colorDepth) { return colorDepth.toInt(); });
const QVariantList toolchainVersions = toolchain.value("versions").toArray().toVariantList();
const auto toolchainVersionsVector = Utils::transform<QVector<QString> >(
toolchainVersions, [&](const QVariant &version) { return version.toString(); });
@@ -653,21 +665,76 @@ static McuTargetDescription parseDescriptionJson(const QByteArray &data)
boardSdkVersions, [&](const QVariant &version) { return version.toString(); });
return {
target.value("qulVersion").toString(),
qulVersion,
compatVersion,
{},
{
toolchain.value("id").toString(),
toolchainVersionsVector,
},
{
boardSdk.value("name").toString(),
boardSdk.value("defaultPath").toString(),
boardSdk.value("envVar").toString(),
boardSdkVersionsVector,
},
{
freeRTOS.value("envVar").toString(),
freeRTOS.value("boardSdkSubDir").toString(),
}
};
}
static McuTargetDescription parseDescriptionJsonV1x(const QString &qulVersion, const QJsonObject &target)
{
auto description = parseDescriptionJsonCommon(qulVersion, target);
const QVariantList colorDepths = target.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int> >(
colorDepths, [&](const QVariant &colorDepth) { return colorDepth.toInt(); });
description.platform = {
target.value("platform").toString(),
target.value("platformName").toString(),
target.value("platformVendor").toString(),
colorDepthsVector,
toolchain.value("id").toString(),
toolchainVersionsVector,
boardSdk.value("envVar").toString(),
boardSdk.value("name").toString(),
boardSdk.value("defaultPath").toString(),
boardSdkVersionsVector,
freeRTOS.value("envVar").toString(),
freeRTOS.value("boardSdkSubDir").toString(),
boardSdk.empty() ? McuTargetDescription::TargetType::Desktop : McuTargetDescription::TargetType::MCU
description.boardSdk.envVar.isEmpty() ? McuTargetDescription::TargetType::Desktop : McuTargetDescription::TargetType::MCU
};
return description;
}
static McuTargetDescription parseDescriptionJsonV2x(const QString &qulVersion, const QJsonObject &target)
{
const QJsonObject platform = target.value("platform").toObject();
const QVariantList colorDepths = platform.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int> >(
colorDepths, [&](const QVariant &colorDepth) { return colorDepth.toInt(); });
const QString platformName = platform.value("platformName").toString();
McuTargetDescription description = parseDescriptionJsonCommon(qulVersion, target);
description.platform = {
platform.value("id").toString(),
platformName,
platform.value("vendor").toString(),
colorDepthsVector,
platformName == "Desktop" ? McuTargetDescription::TargetType::Desktop : McuTargetDescription::TargetType::MCU,
};
return description;
}
static McuTargetDescription parseDescriptionJson(const QByteArray &data)
{
const QJsonDocument document = QJsonDocument::fromJson(data);
const QJsonObject target = document.object();
const QString qulVersion = target.value("qulVersion").toString();
switch (QVersionNumber::fromString(qulVersion).majorVersion()) {
case 1: return parseDescriptionJsonV1x(qulVersion, target);
case 2: return parseDescriptionJsonV2x(qulVersion, target);
default: return { qulVersion };
}
}
// https://doc.qt.io/qtcreator/creator-developing-mcu.html#supported-qt-for-mcus-sdks
@@ -695,8 +762,7 @@ bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message)
return false;
}
void targetsAndPackages(const Utils::FilePath &dir, QVector<McuPackage *> *packages,
QVector<McuTarget *> *mcuTargets)
void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo)
{
QList<McuTargetDescription> descriptions;
@@ -706,8 +772,17 @@ void targetsAndPackages(const Utils::FilePath &dir, QVector<McuPackage *> *packa
if (!file.open(QFile::ReadOnly))
continue;
const McuTargetDescription desc = parseDescriptionJson(file.readAll());
if (QVersionNumber::fromString(desc.qulVersion) < McuSupportOptions::minimalQulVersion()) {
const auto pth = Utils::FilePath::fromString(fileInfo.filePath());
bool ok = false;
const int compatVersion = desc.compatVersion.toInt(&ok);
if (!desc.compatVersion.isEmpty() && ok && compatVersion > MAX_COMPATIBILITY_VERSION) {
printMessage(McuTarget::tr("Skipped %1. Unsupported version \"%2\".").arg(
QDir::toNativeSeparators(pth.fileNameWithPathComponents(1)),
desc.qulVersion),
false);
continue;
}
if (QVersionNumber::fromString(desc.qulVersion) < McuSupportOptions::minimalQulVersion()) {
const QString qtcSupportText = oldSdkQtcRequiredVersion.contains(desc.qulVersion) ?
McuTarget::tr("Detected version \"%1\", only supported by Qt Creator %2.")
.arg(desc.qulVersion, oldSdkQtcRequiredVersion.value(desc.qulVersion))
@@ -744,7 +819,7 @@ void targetsAndPackages(const Utils::FilePath &dir, QVector<McuPackage *> *packa
// This whole section could be removed when minimalQulVersion will reach 1.5 or above
{
const bool hasDesktopDescription = Utils::contains(descriptions, [](const McuTargetDescription &desc) {
return desc.type == McuTargetDescription::TargetType::Desktop;
return desc.platform.type == McuTargetDescription::TargetType::Desktop;
});
if (!hasDesktopDescription) {
@@ -764,12 +839,12 @@ void targetsAndPackages(const Utils::FilePath &dir, QVector<McuPackage *> *packa
desktopDescription.qulVersion = descriptions.empty() ?
McuSupportOptions::minimalQulVersion().toString()
: descriptions.first().qulVersion;
desktopDescription.platform = "Qt";
desktopDescription.platformName = "Desktop";
desktopDescription.platformVendor = "Qt";
desktopDescription.colorDepths = {32};
desktopDescription.toolchainId = Utils::HostOsInfo::isWindowsHost() ? QString("msvc") : QString("gcc");
desktopDescription.type = McuTargetDescription::TargetType::Desktop;
desktopDescription.platform.id = "Qt";
desktopDescription.platform.name = "Desktop";
desktopDescription.platform.vendor = "Qt";
desktopDescription.platform.colorDepths = {32};
desktopDescription.toolchain.id = Utils::HostOsInfo::isWindowsHost() ? QString("msvc") : QString("gcc");
desktopDescription.platform.type = McuTargetDescription::TargetType::Desktop;
descriptions.prepend(desktopDescription);
} else {
if (dir.exists())
@@ -782,10 +857,10 @@ void targetsAndPackages(const Utils::FilePath &dir, QVector<McuPackage *> *packa
}
}
mcuTargets->append(targetsFromDescriptions(descriptions, packages));
repo->mcuTargets.append(targetsFromDescriptions(descriptions, &(repo->packages)));
// Keep targets sorted lexicographically
std::sort(mcuTargets->begin(), mcuTargets->end(), [] (const McuTarget* lhs, const McuTarget* rhs) {
std::sort(repo->mcuTargets.begin(), repo->mcuTargets.end(), [] (const McuTarget* lhs, const McuTarget* rhs) {
return McuSupportOptions::kitName(lhs) < McuSupportOptions::kitName(rhs);
});
}

View File

@@ -33,17 +33,18 @@ class FilePath;
namespace McuSupport {
namespace Internal {
class McuPackage;
#define MAX_COMPATIBILITY_VERSION 1
class McuSdkRepository;
class McuToolChainPackage;
class McuTarget;
namespace Sdk {
McuPackage *createQtForMCUsPackage();
bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message);
void targetsAndPackages(const Utils::FilePath &qulDir,
QVector<McuPackage*> *packages, QVector<McuTarget*> *mcuTargets);
void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo);
Utils::FilePath kitsPath(const Utils::FilePath &dir);

View File

@@ -14,6 +14,10 @@ else()
endif()
qul_target_qml_sources(%{ProjectName} %{MainQmlFile})
app_target_setup_os(%{ProjectName})
if(Qul_VERSION VERSION_GREATER_EQUAL "2.0")
app_target_default_entrypoint(%{ProjectName} %{RootItemName})
else()
app_target_default_main(%{ProjectName} %{RootItemName})
endif()