diff options
author | Christiaan Janssen <christiaan.janssen@qt.io> | 2021-09-29 17:23:11 +0200 |
---|---|---|
committer | Christiaan Janssen <christiaan.janssen@qt.io> | 2021-10-26 16:00:30 +0000 |
commit | 0eeb6c6e5edb9c90505b1cf4cebb9c1247e87fbe (patch) | |
tree | 15983897ed4c03fefc861775ea46f814acf3c30a | |
parent | 9edecd1c94656eedf6293b4749ba84a968c4aa25 (diff) |
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>
-rw-r--r-- | src/plugins/mcusupport/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupport.pro | 6 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupport.qbs | 2 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportcmakemapper.cpp | 76 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportcmakemapper.h | 35 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportoptions.cpp | 105 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportoptions.h | 11 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportoptionspage.cpp | 12 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportsdk.cpp | 251 | ||||
-rw-r--r-- | src/plugins/mcusupport/mcusupportsdk.h | 9 | ||||
-rw-r--r-- | src/plugins/mcusupport/wizards/application/CMakeLists.txt | 8 |
11 files changed, 374 insertions, 142 deletions
diff --git a/src/plugins/mcusupport/CMakeLists.txt b/src/plugins/mcusupport/CMakeLists.txt index 3729ac7256..a85b35b5f9 100644 --- a/src/plugins/mcusupport/CMakeLists.txt +++ b/src/plugins/mcusupport/CMakeLists.txt @@ -12,4 +12,5 @@ add_qtc_plugin(McuSupport mcusupportsdk.cpp mcusupportsdk.h mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h mcusupportversiondetection.cpp mcusupportversiondetection.h + mcusupportcmakemapper.cpp mcusupportcmakemapper.h ) diff --git a/src/plugins/mcusupport/mcusupport.pro b/src/plugins/mcusupport/mcusupport.pro index f2d7a1c501..e03db38925 100644 --- a/src/plugins/mcusupport/mcusupport.pro +++ b/src/plugins/mcusupport/mcusupport.pro @@ -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 diff --git a/src/plugins/mcusupport/mcusupport.qbs b/src/plugins/mcusupport/mcusupport.qbs index 8818514b2b..2f775a0154 100644 --- a/src/plugins/mcusupport/mcusupport.qbs +++ b/src/plugins/mcusupport/mcusupport.qbs @@ -32,5 +32,7 @@ QtcPlugin { "mcusupportrunconfiguration.h", "mcusupportversiondetection.cpp", "mcusupportversiondetection.h", + "mcusupportcmakemapper.h", + "mcusupportcmakemapper.cpp" ] } diff --git a/src/plugins/mcusupport/mcusupportcmakemapper.cpp b/src/plugins/mcusupport/mcusupportcmakemapper.cpp new file mode 100644 index 0000000000..326489e365 --- /dev/null +++ b/src/plugins/mcusupport/mcusupportcmakemapper.cpp @@ -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(); + }); +} diff --git a/src/plugins/mcusupport/mcusupportcmakemapper.h b/src/plugins/mcusupport/mcusupportcmakemapper.h new file mode 100644 index 0000000000..f5da2092de --- /dev/null +++ b/src/plugins/mcusupport/mcusupportcmakemapper.h @@ -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 diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index ba6107d6fc..6ac2e30fd1 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -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; } diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 346c2b9de5..e33af08492 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -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(); diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index 71eff41c24..f4b79ec0f2 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -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(); diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 291f0647b2..a9cdf7a976 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -331,19 +331,28 @@ struct McuTargetDescription }; QString qulVersion; - QString platform; - QString platformName; - QString platformVendor; - QVector<int> colorDepths; - QString toolchainId; - QVector<QString> toolchainVersions; - QString boardSdkEnvVar; - QString boardSdkName; - QString boardSdkDefaultPath; - QVector<QString> boardSdkVersions; - QString freeRTOSEnvVar; - QString freeRTOSBoardSdkSubDir; - TargetType type; + QString compatVersion; + struct { + QString id; + QString name; + QString vendor; + QVector<int> colorDepths; + 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(), - target.value("platform").toString(), - target.value("platformName").toString(), - target.value("platformVendor").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, + 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, - 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 + 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()); + 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 auto pth = Utils::FilePath::fromString(fileInfo.filePath()); 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); }); } diff --git a/src/plugins/mcusupport/mcusupportsdk.h b/src/plugins/mcusupport/mcusupportsdk.h index f7519919e5..c264b32045 100644 --- a/src/plugins/mcusupport/mcusupportsdk.h +++ b/src/plugins/mcusupport/mcusupportsdk.h @@ -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); diff --git a/src/plugins/mcusupport/wizards/application/CMakeLists.txt b/src/plugins/mcusupport/wizards/application/CMakeLists.txt index e86a8fb6ac..71c4e02343 100644 --- a/src/plugins/mcusupport/wizards/application/CMakeLists.txt +++ b/src/plugins/mcusupport/wizards/application/CMakeLists.txt @@ -14,6 +14,10 @@ else() endif() qul_target_qml_sources(%{ProjectName} %{MainQmlFile}) - app_target_setup_os(%{ProjectName}) -app_target_default_main(%{ProjectName} %{RootItemName}) + +if(Qul_VERSION VERSION_GREATER_EQUAL "2.0") + app_target_default_entrypoint(%{ProjectName} %{RootItemName}) +else() + app_target_default_main(%{ProjectName} %{RootItemName}) +endif() |