diff --git a/src/plugins/mcusupport/CMakeLists.txt b/src/plugins/mcusupport/CMakeLists.txt index 3729ac7256c..a85b35b5f9b 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 f2d7a1c501c..e03db38925d 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 8818514b2b5..2f775a01549 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 00000000000..326489e365c --- /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 + +namespace { +static const QHash &envVarToCMakeVarMapping() +{ + static const QHash 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 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 00000000000..f5da2092def --- /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 mapEnvVarsToQul2xCmakeVars( + const Utils::EnvironmentItems &envVars); +} +} // namespace McuSupport diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index ba6107d6fc6..6ac2e30fd13 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 #include @@ -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 packages; - QVector 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 packages; - QVector 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 packages; - QVector 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 packages; - QVector 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 346c2b9de50..e33af08492b 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 packages; + QVector mcuTargets; + + void deletePackagesAndTargets(); +}; + class McuSupportOptions : public QObject { Q_OBJECT @@ -214,9 +222,8 @@ public: McuSupportOptions(QObject *parent = nullptr); ~McuSupportOptions() override; - QVector packages; - QVector 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 71eff41c246..f4b79ec0f2e 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(m_options.mcuTargets, [](McuTarget *t) { + Utils::transform(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 291f0647b29..a9cdf7a976f 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 colorDepths; - QString toolchainId; - QVector toolchainVersions; - QString boardSdkEnvVar; - QString boardSdkName; - QString boardSdkDefaultPath; - QVector boardSdkVersions; - QString freeRTOSEnvVar; - QString freeRTOSBoardSdkSubDir; - TargetType type; + QString compatVersion; + struct { + QString id; + QString name; + QString vendor; + QVector colorDepths; + TargetType type; + } platform; + struct { + QString id; + QVector versions; + } toolchain; + struct { + QString name; + QString defaultPath; + QString envVar; + QVector 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 createMcuTargetsLegacy(const McuTargetDescription &desc) { QVector 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 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 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 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 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 >( - colorDepths, [&](const QVariant &colorDepth) { return colorDepth.toInt(); }); const QVariantList toolchainVersions = toolchain.value("versions").toArray().toVariantList(); const auto toolchainVersionsVector = Utils::transform >( toolchainVersions, [&](const QVariant &version) { return version.toString(); }); @@ -653,23 +665,78 @@ 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(), - 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 + 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 >( + 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 >( + 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 const QHash oldSdkQtcRequiredVersion = { {{"1.0"}, {"4.11.x"}}, @@ -695,8 +762,7 @@ bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message) return false; } -void targetsAndPackages(const Utils::FilePath &dir, QVector *packages, - QVector *mcuTargets) +void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo) { QList descriptions; @@ -706,8 +772,17 @@ void targetsAndPackages(const Utils::FilePath &dir, QVector *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 *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 *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 *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 f7519919e5f..c264b32045b 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 *packages, QVector *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 e86a8fb6ac9..71c4e023432 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()