diff --git a/src/plugins/mcusupport/mcuabstracttargetfactory.h b/src/plugins/mcusupport/mcuabstracttargetfactory.h index 8840561d63d..bc36a2c8b3f 100644 --- a/src/plugins/mcusupport/mcuabstracttargetfactory.h +++ b/src/plugins/mcusupport/mcuabstracttargetfactory.h @@ -32,10 +32,15 @@ #include +namespace Utils { +class FilePath; +} // namespace Utils + namespace McuSupport::Internal { namespace Sdk { struct McuTargetDescription; +} //namespace Sdk class McuAbstractTargetFactory { @@ -43,10 +48,11 @@ public: using Ptr = std::unique_ptr; virtual ~McuAbstractTargetFactory() = default; - virtual QPair createTargets(const McuTargetDescription &) = 0; + virtual QPair createTargets(const Sdk::McuTargetDescription &, + const Utils::FilePath &qtForMcuPath) + = 0; using AdditionalPackages = QPair, QHash>; virtual AdditionalPackages getAdditionalPackages() const { return {}; } }; // struct McuAbstractTargetFactory -} // namespace Sdk } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index 8160daf5bfb..898783fd737 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "mcukitmanager.h" +#include "mculegacyconstants.h" #include "mcusupportoptions.h" #include "mcukitinformation.h" @@ -121,7 +122,7 @@ public: k->setValue(KIT_MCUTARGET_SDKVERSION_KEY, mcuTarget->qulVersion().toString()); k->setValue(KIT_MCUTARGET_KITVERSION_KEY, KIT_VERSION); k->setValue(KIT_MCUTARGET_OS_KEY, static_cast(mcuTarget->os())); - k->setValue(KIT_MCUTARGET_TOOCHAIN_KEY, mcuTarget->toolChainPackage()->toolChainName()); + k->setValue(KIT_MCUTARGET_TOOLCHAIN_KEY, mcuTarget->toolChainPackage()->toolChainName()); k->setAutoDetected(false); k->makeSticky(); if (mcuTarget->toolChainPackage()->isDesktopToolchain()) @@ -252,11 +253,10 @@ public: } if (!mcuTarget->toolChainPackage()->isDesktopToolchain()) { - const FilePath cMakeToolchainFile = qtForMCUsSdkPackage->path().pathAppended( - "lib/cmake/Qul/toolchain/" - + mcuTarget->toolChainPackage()->cmakeToolChainFileName()); + const FilePath cMakeToolchainFile = mcuTarget->toolChainFilePackage()->path(); - configMap.insert("CMAKE_TOOLCHAIN_FILE", cMakeToolchainFile.toString().toUtf8()); + configMap.insert(Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, + cMakeToolchainFile.toUserOutput().toUtf8()); if (!cMakeToolchainFile.exists()) { printMessage( McuTarget::tr( @@ -402,7 +402,7 @@ QList existingKits(const McuTarget *mcuTarget) && kit->value(KIT_MCUTARGET_COLORDEPTH_KEY) == mcuTarget->colorDepth() && kit->value(KIT_MCUTARGET_OS_KEY).toInt() == static_cast(mcuTarget->os()) - && kit->value(KIT_MCUTARGET_TOOCHAIN_KEY) + && kit->value(KIT_MCUTARGET_TOOLCHAIN_KEY) == mcuTarget->toolChainPackage()->toolChainName())); }); } diff --git a/src/plugins/mcusupport/mculegacyconstants.h b/src/plugins/mcusupport/mculegacyconstants.h new file mode 100644 index 00000000000..945996acc23 --- /dev/null +++ b/src/plugins/mcusupport/mculegacyconstants.h @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +namespace McuSupport::Constants { + +const char QUL_TOOLCHAIN_CMAKE_DIR[] = "lib/cmake/Qul/toolchain/"; +const char QUL_ENV_VAR[] = "Qul_ROOT"; + +} // namespace McuSupport::Constants diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index c8ecdb3d54f..35c87fe2ba0 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -432,11 +432,6 @@ QString McuToolChainPackage::toolChainName() const } } -QString McuToolChainPackage::cmakeToolChainFileName() const -{ - return toolChainName() + QLatin1String(".cmake"); -} - QVariant McuToolChainPackage::debuggerId() const { using namespace Debugger; diff --git a/src/plugins/mcusupport/mcupackage.h b/src/plugins/mcusupport/mcupackage.h index 26592e46a1a..2b8b1a89b9f 100644 --- a/src/plugins/mcusupport/mcupackage.h +++ b/src/plugins/mcusupport/mcupackage.h @@ -136,7 +136,6 @@ public: bool isDesktopToolchain() const; ProjectExplorer::ToolChain *toolChain(Utils::Id language) const; QString toolChainName() const; - QString cmakeToolChainFileName() const; QVariant debuggerId() const; private: diff --git a/src/plugins/mcusupport/mcusupportconstants.h b/src/plugins/mcusupport/mcusupportconstants.h index 855525b6759..8c707b28495 100644 --- a/src/plugins/mcusupport/mcusupportconstants.h +++ b/src/plugins/mcusupport/mcusupportconstants.h @@ -39,7 +39,7 @@ const char KIT_MCUTARGET_SDKVERSION_KEY[]{"McuSupport.McuTargetSdkVersion"}; const char KIT_MCUTARGET_KITVERSION_KEY[]{"McuSupport.McuTargetKitVersion"}; const char KIT_MCUTARGET_COLORDEPTH_KEY[]{"McuSupport.McuTargetColorDepth"}; const char KIT_MCUTARGET_OS_KEY[]{"McuSupport.McuTargetOs"}; -const char KIT_MCUTARGET_TOOCHAIN_KEY[]{"McuSupport.McuTargetToolchain"}; +const char KIT_MCUTARGET_TOOLCHAIN_KEY[]{"McuSupport.McuTargetToolchain"}; const char SETTINGS_GROUP[]{"McuSupport"}; const char SETTINGS_KEY_PACKAGE_PREFIX[]{"Package_"}; diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 6f8f36a6ee0..9fb416cea6f 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -26,6 +26,7 @@ #include "mcusupportsdk.h" #include "mcuhelpers.h" #include "mcukitmanager.h" +#include "mculegacyconstants.h" #include "mcupackage.h" #include "mcusupportconstants.h" #include "mcusupportoptions.h" @@ -172,10 +173,18 @@ McuPackagePtr createFreeRTOSSourcesPackage(const SettingsHandler::Ptr &settingsH "https://freertos.org")}; // download url } -McuPackagePtr createUnsupportedToolChainFilePackage(const SettingsHandler::Ptr &settingsHandler) +McuPackagePtr createUnsupportedToolChainFilePackage(const SettingsHandler::Ptr &settingsHandler, + const FilePath &qtForMCUSdkPath) { - return McuPackagePtr{ - new McuPackage(settingsHandler, {}, {}, {}, {}, Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, {})}; + const FilePath toolchainFilePath = qtForMCUSdkPath / Constants::QUL_TOOLCHAIN_CMAKE_DIR + / "unsupported.cmake"; + return McuPackagePtr{new McuPackage(settingsHandler, + {}, + toolchainFilePath, + {}, + {}, + Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, + {})}; } McuToolChainPackagePtr createUnsupportedToolChainPackage(const SettingsHandler::Ptr &settingsHandler) @@ -444,18 +453,58 @@ static McuPackagePtr createRenesasProgrammerPackage(const SettingsHandler::Ptr & } static McuAbstractTargetFactory::Ptr createFactory(bool isLegacy, - const SettingsHandler::Ptr &settingsHandler) + const SettingsHandler::Ptr &settingsHandler, + const FilePath &qtMcuSdkPath) { McuAbstractTargetFactory::Ptr result; if (isLegacy) { - static const QHash toolchainCompilers = { - {{"armgcc"}, McuToolChainPackagePtr{createArmGccToolchainPackage(settingsHandler)}}, - {{"greenhills"}, McuToolChainPackagePtr{createGhsToolchainPackage(settingsHandler)}}, - {{"iar"}, McuToolChainPackagePtr{createIarToolChainPackage(settingsHandler)}}, - {{"msvc"}, McuToolChainPackagePtr{createMsvcToolChainPackage(settingsHandler)}}, - {{"gcc"}, McuToolChainPackagePtr{createGccToolChainPackage(settingsHandler)}}, + static const QHash toolchainCreators = { + {{"armgcc"}, + {[settingsHandler] { return createArmGccToolchainPackage(settingsHandler); }}}, + {{"greenhills"}, + [settingsHandler] { return createGhsToolchainPackage(settingsHandler); }}, + {{"iar"}, {[settingsHandler] { return createIarToolChainPackage(settingsHandler); }}}, + {{"msvc"}, {[settingsHandler] { return createMsvcToolChainPackage(settingsHandler); }}}, + {{"gcc"}, {[settingsHandler] { return createGccToolChainPackage(settingsHandler); }}}, {{"arm-greenhills"}, - McuToolChainPackagePtr{createGhsArmToolchainPackage(settingsHandler)}}, + {[settingsHandler] { return createGhsArmToolchainPackage(settingsHandler); }}}, + }; + + const FilePath toolchainFilePrefix = qtMcuSdkPath / Constants::QUL_TOOLCHAIN_CMAKE_DIR; + static const QHash toolchainFiles = { + {{"armgcc"}, + McuPackagePtr{new McuPackage{settingsHandler, + {}, + toolchainFilePrefix / "armgcc.cmake", + {}, + {}, + Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, + {}}}}, + + {{"iar"}, + McuPackagePtr{new McuPackage{settingsHandler, + {}, + toolchainFilePrefix / "iar.cmake", + {}, + {}, + Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, + {}}}}, + {"greenhills", + McuPackagePtr{new McuPackage{settingsHandler, + {}, + toolchainFilePrefix / "ghs.cmake", + {}, + {}, + Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, + {}}}}, + {"arm-greenhills", + McuPackagePtr{new McuPackage{settingsHandler, + {}, + toolchainFilePrefix / "arm-ghs.cmake", + {}, + {}, + Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, + {}}}}, }; // Note: the vendor name (the key of the hash) is case-sensitive. It has to match the "platformVendor" key in the @@ -467,7 +516,8 @@ static McuAbstractTargetFactory::Ptr createFactory(bool isLegacy, {{"RENESAS"}, McuPackagePtr{createRenesasProgrammerPackage(settingsHandler)}}, }; - result = std::make_unique(toolchainCompilers, + result = std::make_unique(toolchainCreators, + toolchainFiles, vendorPkgs, settingsHandler); } else { @@ -478,14 +528,17 @@ static McuAbstractTargetFactory::Ptr createFactory(bool isLegacy, McuSdkRepository targetsFromDescriptions(const QList &descriptions, const SettingsHandler::Ptr &settingsHandler, + const FilePath &qtForMCUSdkPath, bool isLegacy) { Targets mcuTargets; Packages mcuPackages; - McuAbstractTargetFactory::Ptr targetFactory = createFactory(isLegacy, settingsHandler); + McuAbstractTargetFactory::Ptr targetFactory = createFactory(isLegacy, + settingsHandler, + qtForMCUSdkPath); for (const McuTargetDescription &desc : descriptions) { - auto [targets, packages] = targetFactory->createTargets(desc); + auto [targets, packages] = targetFactory->createTargets(desc, qtForMCUSdkPath); mcuTargets.append(targets); mcuPackages.unite(packages); } @@ -502,9 +555,9 @@ McuSdkRepository targetsFromDescriptions(const QList &desc return McuSdkRepository{mcuTargets, mcuPackages}; } -Utils::FilePath kitsPath(const Utils::FilePath &dir) +Utils::FilePath kitsPath(const Utils::FilePath &qtMcuSdkPath) { - return dir / "kits/"; + return qtMcuSdkPath / "kits/"; } static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir) @@ -513,20 +566,25 @@ static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir) return kitsDir.entryInfoList(); } +static PackageDescription parsePackage(const QJsonObject &cmakeEntry) +{ + return {cmakeEntry["label"].toString(), + cmakeEntry["envVar"].toString(), + cmakeEntry["cmakeVar"].toString(), + cmakeEntry["description"].toString(), + cmakeEntry["setting"].toString(), + FilePath::fromString(cmakeEntry["defaultValue"].toString()), + FilePath::fromString(cmakeEntry["validation"].toString()), + {}, + false}; +} + static QList parsePackages(const QJsonArray &cmakeEntries) { QList result; for (const auto &cmakeEntryRef : cmakeEntries) { const QJsonObject cmakeEntry{cmakeEntryRef.toObject()}; - result.push_back({cmakeEntry["label"].toString(), - cmakeEntry["envVar"].toString(), - cmakeEntry["cmakeVar"].toString(), - cmakeEntry["description"].toString(), - cmakeEntry["setting"].toString(), - FilePath::fromString(cmakeEntry["defaultValue"].toString()), - FilePath::fromString(cmakeEntry["validation"].toString()), - {}, - false}); + result.push_back(parsePackage(cmakeEntry)); } return result; } @@ -539,11 +597,13 @@ McuTargetDescription parseDescriptionJson(const QByteArray &data) const QJsonObject platform = target.value("platform").toObject(); const QString compatVersion = target.value("compatVersion").toString(); const QJsonObject toolchain = target.value("toolchain").toObject(); + const QJsonObject toolchainFile = toolchain.value("file").toObject(); + const QJsonObject compiler = toolchain.value("compiler").toObject(); const QJsonObject boardSdk = target.value("boardSdk").toObject(); const QJsonObject freeRTOS = target.value("freeRTOS").toObject(); - const QList toolchainEntries = parsePackages( - toolchain.value(CMAKE_ENTRIES).toArray()); + const PackageDescription toolchainPackage = parsePackage(compiler); + const PackageDescription toolchainFilePackage = parsePackage(toolchainFile); const QList boardSDKEntries = parsePackages( boardSdk.value(CMAKE_ENTRIES).toArray()); const QList freeRtosEntries = parsePackages( @@ -577,7 +637,10 @@ McuTargetDescription parseDescriptionJson(const QByteArray &data) platformName == "Desktop" ? McuTargetDescription::TargetType::Desktop : McuTargetDescription::TargetType::MCU, }, - {toolchain.value("id").toString(), toolchainVersionsList, toolchainEntries}, + {toolchain.value("id").toString(), + toolchainVersionsList, + toolchainPackage, + toolchainFilePackage}, { boardSdk.value("name").toString(), FilePath::fromString(boardSdk.value("defaultPath").toString()), @@ -683,7 +746,10 @@ McuSdkRepository targetsAndPackages(const Utils::FilePath &qtForMCUSdkPath, } } } - McuSdkRepository repo = targetsFromDescriptions(descriptions, settingsHandler, isLegacy); + McuSdkRepository repo = targetsFromDescriptions(descriptions, + settingsHandler, + qtForMCUSdkPath, + isLegacy); // Keep targets sorted lexicographically Utils::sort(repo.mcuTargets, [](const McuTargetPtr &lhs, const McuTargetPtr &rhs) { diff --git a/src/plugins/mcusupport/mcusupportsdk.h b/src/plugins/mcusupport/mcusupportsdk.h index 3f94474da73..3bf8380de9c 100644 --- a/src/plugins/mcusupport/mcusupportsdk.h +++ b/src/plugins/mcusupport/mcusupportsdk.h @@ -32,11 +32,16 @@ #include +namespace Utils { +class FilePath; +} // namespace Utils + namespace McuSupport::Internal { constexpr int MAX_COMPATIBILITY_VERSION{1}; class McuAbstractPackage; +class McuPackage; class McuSdkRepository; class McuTarget; class McuToolChainPackage; @@ -54,11 +59,13 @@ McuSdkRepository targetsAndPackages(const Utils::FilePath &qulDir, const Setting McuTargetDescription parseDescriptionJson(const QByteArray &); McuSdkRepository targetsFromDescriptions(const QList &, const SettingsHandler::Ptr &, + const Utils::FilePath &qtForMCUSdkPath, bool isLegacy); Utils::FilePath kitsPath(const Utils::FilePath &dir); -McuPackagePtr createUnsupportedToolChainFilePackage(const SettingsHandler::Ptr &); +McuPackagePtr createUnsupportedToolChainFilePackage(const SettingsHandler::Ptr &, + const Utils::FilePath &qtMcuSdkPath); McuToolChainPackagePtr createUnsupportedToolChainPackage(const SettingsHandler::Ptr &); McuToolChainPackagePtr createIarToolChainPackage(const SettingsHandler::Ptr &); McuToolChainPackagePtr createGccToolChainPackage(const SettingsHandler::Ptr &); diff --git a/src/plugins/mcusupport/mcutarget.cpp b/src/plugins/mcusupport/mcutarget.cpp index b1cf475671c..c21fc896ea2 100644 --- a/src/plugins/mcusupport/mcutarget.cpp +++ b/src/plugins/mcusupport/mcutarget.cpp @@ -39,12 +39,14 @@ McuTarget::McuTarget(const QVersionNumber &qulVersion, OS os, const Packages &packages, const McuToolChainPackagePtr &toolChainPackage, + const McuPackagePtr &toolChainFilePackage, int colorDepth) : m_qulVersion(qulVersion) , m_platform(platform) , m_os(os) , m_packages(packages) , m_toolChainPackage(toolChainPackage) + , m_toolChainFilePackage(toolChainFilePackage) , m_colorDepth(colorDepth) {} @@ -58,6 +60,11 @@ McuToolChainPackagePtr McuTarget::toolChainPackage() const return m_toolChainPackage; } +McuPackagePtr McuTarget::toolChainFilePackage() const +{ + return m_toolChainFilePackage; +} + McuTarget::OS McuTarget::os() const { return m_os; diff --git a/src/plugins/mcusupport/mcutarget.h b/src/plugins/mcusupport/mcutarget.h index 343eb8a431d..c2c43707a1f 100644 --- a/src/plugins/mcusupport/mcutarget.h +++ b/src/plugins/mcusupport/mcutarget.h @@ -65,11 +65,13 @@ public: OS os, const Packages &packages, const McuToolChainPackagePtr &toolChainPackage, + const McuPackagePtr &toolChainFilePackage, int colorDepth = UnspecifiedColorDepth); QVersionNumber qulVersion() const; Packages packages() const; McuToolChainPackagePtr toolChainPackage() const; + McuPackagePtr toolChainFilePackage() const; Platform platform() const; OS os() const; int colorDepth() const; @@ -82,6 +84,7 @@ private: const OS m_os; const Packages m_packages; McuToolChainPackagePtr m_toolChainPackage; + McuPackagePtr m_toolChainFilePackage; const int m_colorDepth; }; // class McuTarget diff --git a/src/plugins/mcusupport/mcutargetdescription.h b/src/plugins/mcusupport/mcutargetdescription.h index cce2c8e310d..7f261a82176 100644 --- a/src/plugins/mcusupport/mcutargetdescription.h +++ b/src/plugins/mcusupport/mcutargetdescription.h @@ -64,7 +64,8 @@ struct McuTargetDescription { QString id; QStringList versions; - QList packages; + PackageDescription compiler; + PackageDescription file; } toolchain; struct BoardSdk { diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index a02e34b9591..b2e13c71fbd 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -35,14 +35,14 @@ #include -namespace McuSupport::Internal::Sdk { +namespace McuSupport::Internal { + +using Sdk::McuTargetDescription; +using Sdk::PackageDescription; bool isToolchainDescriptionValid(const McuTargetDescription::Toolchain &t) { - bool result{true}; - if (t.packages.isEmpty() || t.id.isEmpty()) - result = false; - return result; + return !t.id.isEmpty() && !t.compiler.cmakeVar.isEmpty() && !t.file.cmakeVar.isEmpty(); } bool isDesktopToolchain(McuToolChainPackage::ToolChainType type) @@ -65,7 +65,8 @@ McuTargetFactory::McuTargetFactory(const SettingsHandler::Ptr &settingsHandler) : settingsHandler{settingsHandler} {} -QPair McuTargetFactory::createTargets(const McuTargetDescription &desc) +QPair McuTargetFactory::createTargets(const McuTargetDescription &desc, + const Utils::FilePath & /*qtForMCUSdkPath*/) { Targets mcuTargets; Packages packages; @@ -75,7 +76,9 @@ QPair McuTargetFactory::createTargets(const McuTargetDescript {desc.platform.id, desc.platform.name, desc.platform.vendor}); auto *toolchain = createToolchain(desc.toolchain); - if (toolchain == nullptr) + McuPackagePtr toolchainFile{createPackage(desc.toolchain.file)}; + //Skip target with incorrect toolchain dir or toolchain file. + if (!toolchain || !toolchainFile) continue; Packages targetPackages = createPackages(desc); packages.unite(targetPackages); @@ -84,6 +87,7 @@ QPair McuTargetFactory::createTargets(const McuTargetDescript deduceOperatingSystem(desc), targetPackages, McuToolChainPackagePtr{toolchain}, + toolchainFile, colorDepth}}); } return {mcuTargets, packages}; @@ -94,7 +98,6 @@ QList aggregatePackageEntries(const McuTargetDescription &de QList result; result.append(desc.boardSdk.packages); result.append(desc.freeRTOS.packages); - result.append(desc.toolchain.packages); return result; } @@ -126,10 +129,7 @@ McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc) McuToolChainPackage *McuTargetFactory::createToolchain( const McuTargetDescription::Toolchain &toolchain) { - const PackageDescription compilerDescription - = Utils::findOrDefault(toolchain.packages, [](const PackageDescription &desc) { - return desc.cmakeVar == Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE; - }); + const PackageDescription compilerDescription{toolchain.compiler}; McuToolChainPackage::ToolChainType toolchainType = toolchainTypeMapping.value(toolchain.id, McuToolChainPackage::ToolChainType::Unsupported); @@ -137,7 +137,7 @@ McuToolChainPackage *McuTargetFactory::createToolchain( if (isDesktopToolchain(toolchainType)) return new McuToolChainPackage{settingsHandler, {}, {}, {}, {}, toolchainType}; else if (!isToolchainDescriptionValid(toolchain)) - return nullptr; + toolchainType = McuToolChainPackage::ToolChainType::Unsupported; return new McuToolChainPackage{ settingsHandler, @@ -148,8 +148,8 @@ McuToolChainPackage *McuTargetFactory::createToolchain( toolchainType, compilerDescription.cmakeVar, compilerDescription.envVar, - nullptr, + nullptr, // McuPackageVersionDetector }; } -} // namespace McuSupport::Internal::Sdk +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcutargetfactory.h b/src/plugins/mcusupport/mcutargetfactory.h index cb421af68d4..56e99d58e6a 100644 --- a/src/plugins/mcusupport/mcutargetfactory.h +++ b/src/plugins/mcusupport/mcutargetfactory.h @@ -29,15 +29,18 @@ #include "mcutargetdescription.h" #include "settingshandler.h" -namespace McuSupport::Internal::Sdk { +namespace McuSupport::Internal { +namespace Sdk { struct PackageDescription; +} // namespace Sdk class McuTargetFactory : public McuAbstractTargetFactory { public: explicit McuTargetFactory(const SettingsHandler::Ptr &); - QPair createTargets(const Sdk::McuTargetDescription &) override; + QPair createTargets(const Sdk::McuTargetDescription &, + const Utils::FilePath &qtForMCUSdkPath) override; Packages createPackages(const Sdk::McuTargetDescription &); McuToolChainPackage *createToolchain(const Sdk::McuTargetDescription::Toolchain &); McuPackagePtr createPackage(const Sdk::PackageDescription &); @@ -46,4 +49,4 @@ private: SettingsHandler::Ptr settingsHandler; }; // struct McuTargetFactory -} // namespace McuSupport::Internal::Sdk +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcutargetfactorylegacy.cpp b/src/plugins/mcusupport/mcutargetfactorylegacy.cpp index fb8d5f21460..bddfe76f59a 100644 --- a/src/plugins/mcusupport/mcutargetfactorylegacy.cpp +++ b/src/plugins/mcusupport/mcutargetfactorylegacy.cpp @@ -34,34 +34,35 @@ #include #include -namespace McuSupport::Internal::Sdk { +namespace McuSupport::Internal { -McuTargetFactoryLegacy::McuTargetFactoryLegacy(const QHash &tcPkgs, - const QHash &vendorPkgs, - const SettingsHandler::Ptr &settingsHandler) - : tcPkgs(tcPkgs) +McuTargetFactoryLegacy::McuTargetFactoryLegacy( + const QHash &toolchainCreators, + const QHash &toolchainFiles, + const QHash &vendorPkgs, + const SettingsHandler::Ptr &settingsHandler) + : toolchainCreators(toolchainCreators) + , toolchainFiles(toolchainFiles) , vendorPkgs(vendorPkgs) , settingsHandler(settingsHandler) {} -QPair McuTargetFactoryLegacy::createTargets(const McuTargetDescription &desc) +QPair McuTargetFactoryLegacy::createTargets(const Sdk::McuTargetDescription &desc, + const Utils::FilePath &qtForMcuPath) { QHash boardSdkPkgs; QHash freeRTOSPkgs; Targets mcuTargets; Packages packages; - McuToolChainPackagePtr tcPkg = tcPkgs.value(desc.toolchain.id); - if (tcPkg) { - tcPkg->setVersions(desc.toolchain.versions); - } else { - tcPkg = createUnsupportedToolChainPackage(settingsHandler); - } + McuToolChainPackagePtr toolchainPackage = getToolchainCompiler(desc.toolchain); + McuPackagePtr toolchainFilePackage = getToolchainFile(qtForMcuPath, desc.toolchain.id); for (int colorDepth : desc.platform.colorDepths) { Packages required3rdPartyPkgs; // Desktop toolchains don't need any additional settings - if (tcPkg && !tcPkg->isDesktopToolchain() - && tcPkg->toolchainType() != McuToolChainPackage::ToolChainType::Unsupported) { - required3rdPartyPkgs.insert(tcPkg); + if (toolchainPackage && !toolchainPackage->isDesktopToolchain() + && toolchainPackage->toolchainType() + != McuToolChainPackage::ToolChainType::Unsupported) { + required3rdPartyPkgs.insert(toolchainPackage); } // Add setting specific to platform IDE. @@ -103,7 +104,8 @@ QPair McuTargetFactoryLegacy::createTargets(const McuTargetDe platform, deduceOperatingSystem(desc), required3rdPartyPkgs, - tcPkg, + toolchainPackage, + toolchainFilePackage, colorDepth}}); } return {mcuTargets, packages}; @@ -111,6 +113,28 @@ QPair McuTargetFactoryLegacy::createTargets(const McuTargetDe McuAbstractTargetFactory::AdditionalPackages McuTargetFactoryLegacy::getAdditionalPackages() const { - return {tcPkgs, vendorPkgs}; + return {{}, vendorPkgs}; } -} // namespace McuSupport::Internal::Sdk + +McuToolChainPackagePtr McuTargetFactoryLegacy::getToolchainCompiler( + const Sdk::McuTargetDescription::Toolchain &desc) const +{ + auto compilerCreator = toolchainCreators.value(desc.id, [this] { + return McuToolChainPackagePtr{Sdk::createUnsupportedToolChainPackage(settingsHandler)}; + }); + McuToolChainPackagePtr toolchainPackage = compilerCreator(); + toolchainPackage->setVersions(desc.versions); + return toolchainPackage; +} + +McuPackagePtr McuTargetFactoryLegacy::getToolchainFile(const Utils::FilePath &qtForMCUSdkPath, + const QString &toolchainName) const +{ + if (McuPackagePtr toolchainFile = toolchainFiles.value(toolchainName); toolchainFile) { + return toolchainFile; + } else { + return McuPackagePtr{ + Sdk::createUnsupportedToolChainFilePackage(settingsHandler, qtForMCUSdkPath)}; + } +} +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcutargetfactorylegacy.h b/src/plugins/mcusupport/mcutargetfactorylegacy.h index bfadfe23bcc..9a08bff83d8 100644 --- a/src/plugins/mcusupport/mcutargetfactorylegacy.h +++ b/src/plugins/mcusupport/mcutargetfactorylegacy.h @@ -29,26 +29,38 @@ #include "mcutargetdescription.h" #include "settingshandler.h" +#include #include #include -namespace McuSupport::Internal::Sdk { +namespace McuSupport::Internal { + +class McuPackage; + +using ToolchainCompilerCreator = std::function; class McuTargetFactoryLegacy : public McuAbstractTargetFactory { public: - McuTargetFactoryLegacy(const QHash &tcPkgs, + McuTargetFactoryLegacy(const QHash &toolchainCreators, + const QHash &toolchainFiles, const QHash &vendorPkgs, const SettingsHandler::Ptr &); - QPair createTargets(const McuTargetDescription &) override; + QPair createTargets(const Sdk::McuTargetDescription &, + const Utils::FilePath &qtForMCUSdkPath) override; AdditionalPackages getAdditionalPackages() const override; + McuToolChainPackagePtr getToolchainCompiler(const Sdk::McuTargetDescription::Toolchain &) const; + McuPackagePtr getToolchainFile(const Utils::FilePath &qtForMCUSdkPath, + const QString &toolchainName) const; + private: - const QHash tcPkgs; + QHash toolchainCreators; + const QHash toolchainFiles; const QHash vendorPkgs; SettingsHandler::Ptr settingsHandler; }; // struct McuTargetFactoryLegacy -} // namespace McuSupport::Internal::Sdk +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h b/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h index 44766d16e9e..a45175e93ec 100644 --- a/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h +++ b/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h @@ -42,6 +42,7 @@ constexpr auto armgcc_nxp_1050_json = R"({ "label": "Qt for MCUs SDK", "type": "path", "cmakeVar": "Qul_ROOT", + "envVar": "Qul_DIR", "optional": false }, { @@ -62,8 +63,7 @@ constexpr auto armgcc_nxp_1050_json = R"({ "versions": [ "9.3.1" ], - "cmakeEntries": [ - { + "compiler": { "id": "ARMGCC_DIR", "label": "GNU Arm Embedded Toolchain", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", @@ -72,16 +72,15 @@ constexpr auto armgcc_nxp_1050_json = R"({ "type": "path", "optional": false }, - { + "file": { "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", "label": "CMake Toolchain File", "cmakeVar": "CMAKE_TOOLCHAIN_FILE", "type": "file", - "defaultValue": "$Qul_ROOT/lib/cmake/Qul/toolchain/armgcc.cmake", + "defaultValue": "/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/armgcc.cmake", "visible": false, "optional": false } - ] }, "boardSdk": { "envVar": "EVKB_IMXRT1050_SDK_PATH", diff --git a/src/plugins/mcusupport/test/armgcc_nxp_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_nxp_mimxrt1170_evk_freertos_json.h new file mode 100644 index 00000000000..b4057e84489 --- /dev/null +++ b/src/plugins/mcusupport/test/armgcc_nxp_mimxrt1170_evk_freertos_json.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +constexpr auto armgcc_nxp_mimxrt1170_evk_freertos_json = R"({ + "qulVersion": "2.1.5", + "compatVersion": "1", + "platform": { + "id": "MIMXRT1170-EVK-FREERTOS", + "vendor": "NXP", + "colorDepths": [ + 32 + ], + "pathEntries": [], + "environmentEntries": [], + "cmakeEntries": [ + { + "id": "Qul_DIR", + "description": "Qt for MCUs SDK", + "type": "path", + "cmakeVar": "Qul_ROOT", + "optional": false + }, + { + "id": "MCU_XPRESSO_PATH", + "description": "MCUXpresso IDE", + "type": "path", + "cmakeVar": "MCUXPRESSO_IDE_PATH", + "defaultValue": { + "windows": "$ROOT/nxp/MCUXpressoIDE*", + "unix": "/usr/local/mcuxpressoide/" + }, + "optional": false + } + ] + }, + "toolchain": { + "id": "armgcc", + "versions": [ + "9.3.1" + ], + "compiler": { + "id": "ARMGCC_DIR", + "label": "GNU Arm Embedded Toolchain", + "description": "GNU Arm Embedded Toolchain", + "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", + "envVar": "ARMGCC_DIR", + "setting": "GNUArmEmbeddedToolchain", + "type": "path", + "optional": false + }, + "file": { + "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", + "label": "CMake Toolchain File", + "description": "CMake Toolchain File", + "cmakeVar": "CMAKE_TOOLCHAIN_FILE", + "type": "file", + "defaultValue": "/opt/qtformcu/2.2//lib/cmake/Qul/toolchain/armgcc.cmake", + "visible": false, + "optional": false + } + }, + "boardSdk": { + "envVar": "EVK_MIMXRT1170_SDK_PATH", + "versions": [ + "2.10.1" + ], + "cmakeEntries": [ + { + "id": "NXP_SDK_DIR", + "description": "Board SDK for MIMXRT1170-EVK", + "cmakeVar": "QUL_BOARD_SDK_DIR", + "type": "path", + "optional": false + } + ] + }, + "freeRTOS": { + "envVar": "EVK_MIMXRT1170_FREERTOS_PATH", + "cmakeEntries": [ + { + "id": "NXP_FREERTOS_DIR", + "description": "FreeRTOS SDK for MIMXRT1170-EVK", + "cmakeVar": "FREERTOS_DIR", + "defaultValue": "$QUL_BOARD_SDK_DIR/rtos/freertos/freertos_kernel", + "type": "path", + "optional": false + } + ] + } +})"; diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_freertos_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_freertos_json.h index d8fbca0909a..df260db98dc 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_freertos_json.h @@ -63,8 +63,7 @@ constexpr auto armgcc_stm32f769i_freertos_json = R"({ "versions": [ "9.3.1" ], - "cmakeEntries": [ - { + "compiler": { "id": "ARMGCC_DIR", "label": "GNU Arm Embedded Toolchain", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", @@ -73,16 +72,15 @@ constexpr auto armgcc_stm32f769i_freertos_json = R"({ "type": "path", "optional": false }, - { + "file": { "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", "label": "CMake Toolchain File", "cmakeVar": "CMAKE_TOOLCHAIN_FILE", "type": "file", - "defaultValue": "$Qul_ROOT/lib/cmake/Qul/toolchain/armgcc.cmake", + "defaultValue": "/opt/qtformcu/2.2//lib/cmake/Qul/toolchain/armgcc.cmake", "visible": false, "optional": false } - ] }, "boardSdk": { "envVar": "STM32Cube_FW_F7_SDK_PATH", diff --git a/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h b/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h index 9225f5dc8c9..03545fb83c9 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h @@ -62,8 +62,7 @@ constexpr auto armgcc_stm32h750b_metal_json = R"({ "versions": [ "9.3.1" ], - "cmakeEntries": [ - { + "compiler": { "id": "ARMGCC_DIR", "label": "GNU Arm Embedded Toolchain", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", @@ -72,16 +71,15 @@ constexpr auto armgcc_stm32h750b_metal_json = R"({ "type": "path", "optional": false }, - { + "file" : { "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", "label": "CMake Toolchain File", "cmakeVar": "CMAKE_TOOLCHAIN_FILE", "type": "file", - "defaultValue": "$Qul_ROOT/lib/cmake/Qul/toolchain/armgcc.cmake", + "defaultValue": "/opt/qtformcu/2.2//lib/cmake/Qul/toolchain/armgcc.cmake", "visible": false, "optional": false } - ] }, "boardSdk": { "envVar": "STM32Cube_FW_H7_SDK_PATH", diff --git a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h new file mode 100644 index 00000000000..3a46fe8e17a --- /dev/null +++ b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +constexpr auto ghs_rh850_d1m1a_baremetal_json = R"({ + "qulVersion": "2.1.5", + "compatVersion": "1", + "platform": { + "id": "RH850-D1M1A-BAREMETAL", + "vendor": "RENESAS", + "colorDepths": [ + 32 + ], + "pathEntries": [], + "environmentEntries": [], + "cmakeEntries": [ + { + "id": "Qul_DIR", + "description": "Qt for MCUs SDK", + "type": "path", + "cmakeVar": "Qul_ROOT", + "optional": false + } + ] + }, + "toolchain": { + "id": "greenhills", + "versions": [ + "2018.1.5" + ], + "compiler": { + "description": "Green Hills Compiler", + "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", + "setting": "GHSToolchain", + "label": "Green Hills Compiler", + "type": "path", + "optional": false + }, + "file": { + "description": "CMake Toolchain File", + "cmakeVar": "CMAKE_TOOLCHAIN_FILE", + "type": "file", + "defaultValue": "/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/ghs.cmake", + "visible": false, + "optional": false + } + }, + "boardSdk": { + "envVar": "RGL_DIR", + "versions": [ + "2.0.0a" + ], + "cmakeEntries": [ + { + "id": "RGL_DIR", + "description": "Renesas Graphics Library", + "cmakeVar": "QUL_BOARD_SDK_DIR", + "type": "path", + "defaultValue": "/Renesas_Electronics/D1x_RGL/rgl_ghs_D1Mx_obj_V.2.0.0a", + "optional": false + } + ] + } +})"; diff --git a/src/plugins/mcusupport/test/iar_nxp_1064_json.h b/src/plugins/mcusupport/test/iar_nxp_1064_json.h index d0928574ee8..35eb13517f3 100644 --- a/src/plugins/mcusupport/test/iar_nxp_1064_json.h +++ b/src/plugins/mcusupport/test/iar_nxp_1064_json.h @@ -42,7 +42,6 @@ constexpr auto iar_nxp_1064_json = R"({ "envVar": "EVK_MIMXRT1064_SDK_PATH", "versions": ["2.10.0"] }, - "compatVersion": "1", "freeRTOS": { "cmakeEntries": [ { @@ -81,18 +80,26 @@ constexpr auto iar_nxp_1064_json = R"({ "pathEntries": [], "vendor": "NXP" }, - "qulVersion": "2.0.0", "toolchain": { - "cmakeEntries": [ - { + "id": "iar", + "versions": ["8.50.9"], + "compiler": { "id": "IAR_DIR", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", + "setting": "IARToolchain", + "envVar": "IAR_ARM_COMPILER_DIR", "label": "IAR ARM Compiler", "optional": false, "type": "path" - } - ], - "id": "iar", - "versions": ["8.50.9"] + }, + "file": { + "id": "IAR_CMAKE_TOOLCHAIN_FILE", + "label": "CMake Toolchain File", + "cmakeVar": "CMAKE_TOOLCHAIN_FILE", + "type": "file", + "defaultValue": "/opt/qtformcu/2.2//lib/cmake/Qul/toolchain/iar.cmake", + "visible": false, + "optional": false + } } })"; diff --git a/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h b/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h index 2a4f75a9f53..639ece61af2 100644 --- a/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h @@ -62,8 +62,7 @@ constexpr auto iar_stm32f469i_metal_json = R"({ "versions": [ "8.50.9" ], - "cmakeEntries": [ - { + "compiler": { "id": "IARToolchain", "setting": "IARToolchain", "envVar": "IAR_ARM_COMPILER_DIR", @@ -72,16 +71,15 @@ constexpr auto iar_stm32f469i_metal_json = R"({ "type": "path", "optional": false }, - { + "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", "label": "CMake Toolchain File", "cmakeVar": "CMAKE_TOOLCHAIN_FILE", "type": "file", - "defaultValue": "$Qul_ROOT/lib/cmake/Qul/toolchain/iar.cmake", + "defaultValue": "/opt/qtformcu/2.2//lib/cmake/Qul/toolchain/iar.cmake", "visible": false, "optional": false } - ] }, "boardSdk": { "envVar": "STM32Cube_FW_F4_SDK_PATH", diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index a7375010c8a..e02a456d27d 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -24,19 +24,23 @@ ****************************************************************************/ #include "unittest.h" + #include "armgcc_nxp_1050_json.h" +#include "armgcc_nxp_mimxrt1170_evk_freertos_json.h" #include "armgcc_stm32f769i_freertos_json.h" #include "armgcc_stm32h750b_metal_json.h" #include "gcc_desktop_json.h" +#include "ghs_rh850_d1m1a_baremetal_json.h" #include "iar_nxp_1064_json.h" #include "iar_stm32f469i_metal_json.h" #include "mcuhelpers.h" #include "mcukitmanager.h" +#include "mculegacyconstants.h" #include "mcusupportconstants.h" #include "mcusupportsdk.h" +#include "mcusupportoptions.h" #include "mcutargetdescription.h" -#include "mcutargetfactory.h" #include "mcutargetfactorylegacy.h" #include @@ -45,6 +49,8 @@ #include #include #include +#include +#include #include #include #include @@ -59,30 +65,50 @@ namespace McuSupport::Internal::Test { namespace { -const char id[]{"target_id"}; -const char name[]{"target_name"}; -const char vendor[]{"target_vendor"}; - -const char armgcc[]{"armgcc"}; -const char cmakeExtension[]{".cmake"}; -const char defaultfreeRtosPath[]{"/opt/freertos/default"}; +const char empty[]{""}; +const char armGccDir[]{"/opt/armgcc"}; +const char armGccDirectorySetting[]{"GNUArmEmbeddedToolchain"}; +const char armGccEnvVar[]{"ARMGCC_DIR"}; +const char armGccLabel[]{"GNU Arm Embedded Toolchain"}; +const char armGccToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/armgcc.cmake"}; +const char armGcc[]{"armgcc"}; +const char cmakeToolchainLabel[]{"CMake Toolchain File"}; const char freeRtosCMakeVar[]{"FREERTOS_DIR"}; +const char freeRtosDescription[]{"Freertos directory"}; const char freeRtosEnvVar[]{"EVK_MIMXRT1170_FREERTOS_PATH"}; -const char gcc[]{"armgcc"}; +const char freeRtosLabel[]{"FreeRTOS directory"}; +const char freeRtosPath[]{"/opt/freertos/default"}; +const char freeRtosSetting[]{"Freertos"}; +const char greenhillToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/ghs.cmake"}; +const char greenhillCompilerDir[]{"/abs/ghs"}; +const char greenhillSetting[]{"GHSToolchain"}; +const char iarDir[]{"/opt/iar/compiler"}; const char iarEnvVar[]{"IAR_ARM_COMPILER_DIR"}; const char iarLabel[]{"IAR ARM Compiler"}; const char iarSetting[]{"IARToolchain"}; +const char iarToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/iar.cmake"}; const char iar[]{"iar"}; +const char id[]{"target_id"}; +const char name[]{"target_name"}; const char nxp1050FreeRtosEnvVar[]{"IMXRT1050_FREERTOS_DIR"}; const char nxp1050[]{"IMXRT1050"}; const char nxp1064FreeRtosEnvVar[]{"IMXRT1064_FREERTOS_DIR"}; const char nxp1064[]{"IMXRT1064"}; const char nxp1170FreeRtosEnvVar[]{"EVK_MIMXRT1170_FREERTOS_PATH"}; const char nxp1170[]{"EVK_MIMXRT1170"}; +const char qtForMcuSdkPath[]{"/opt/qtformcu/2.2"}; +const char qulCmakeVar[]{"Qul_ROOT"}; +const char qulEnvVar[]{"Qul_DIR"}; const char stm32f7FreeRtosEnvVar[]{"STM32F7_FREERTOS_DIR"}; const char stm32f7[]{"STM32F7"}; const char unsupported[]{"unsupported"}; -const char cmakeToolchainLabel[]{"CMake Toolchain File"}; +const char vendor[]{"target_vendor"}; +const QString settingsPrefix = QLatin1String(Constants::SETTINGS_GROUP) + '/' + + QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX); +const char qmlToCppSuffixPath[]{"bin/qmltocpp"}; + +const QString unsupportedToolchainFilePath = QString{qtForMcuSdkPath} + + "/lib/cmake/Qul/toolchain/unsupported.cmake"; const QStringList jsonFiles{QString::fromUtf8(armgcc_nxp_1050_json), QString::fromUtf8(iar_nxp_1064_json)}; @@ -90,14 +116,13 @@ const QStringList jsonFiles{QString::fromUtf8(armgcc_nxp_1050_json), const bool runLegacy{true}; const int colorDepth{32}; -const Sdk::McuTargetDescription::Platform platform{id, - "", - "", - {colorDepth}, - Sdk::McuTargetDescription::TargetType::MCU}; +const Sdk::McuTargetDescription::Platform + platformDescription{id, "", "", {colorDepth}, Sdk::McuTargetDescription::TargetType::MCU}; const Utils::Id cxxLanguageId{ProjectExplorer::Constants::CXX_LANGUAGE_ID}; } // namespace +using namespace Utils; + using CMakeProjectManager::CMakeConfigItem; using CMakeProjectManager::CMakeConfigurationKitAspect; using ProjectExplorer::EnvironmentKitAspect; @@ -106,13 +131,18 @@ using ProjectExplorer::KitManager; using ProjectExplorer::ToolChain; using ProjectExplorer::ToolChainManager; +using testing::_; using testing::Return; -using Utils::FilePath; -void verifyIarToolchain(const McuToolChainPackage *iarToolchainPackage) +void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) { + ProjectExplorer::ToolChainFactory toolchainFactory; + Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; + ToolChain *iarToolchain{toolchainFactory.createToolChain(iarId)}; + iarToolchain->setLanguage(cxxLanguageId); + ToolChainManager::instance()->registerToolChain(iarToolchain); + QVERIFY(iarToolchainPackage != nullptr); - QCOMPARE(iarToolchainPackage->cmakeToolChainFileName(), QString{iar}.append(cmakeExtension)); QCOMPARE(iarToolchainPackage->cmakeVariableName(), Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE); QCOMPARE(iarToolchainPackage->environmentVariableName(), iarEnvVar); QCOMPARE(iarToolchainPackage->isDesktopToolchain(), false); @@ -120,22 +150,38 @@ void verifyIarToolchain(const McuToolChainPackage *iarToolchainPackage) QCOMPARE(iarToolchainPackage->toolchainType(), McuToolChainPackage::ToolChainType::IAR); QCOMPARE(iarToolchainPackage->label(), iarLabel); - ProjectExplorer::ToolChainFactory toolchainFactory; - Utils::Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; - ToolChain *iar{toolchainFactory.createToolChain(iarId)}; - iar->setLanguage(cxxLanguageId); - ToolChainManager::instance()->registerToolChain(iar); - - ToolChain *iarToolchain{iarToolchainPackage->toolChain(cxxLanguageId)}; + iarToolchain = iarToolchainPackage->toolChain(cxxLanguageId); QVERIFY(iarToolchain != nullptr); QCOMPARE(iarToolchain->displayName(), "IAREW"); QCOMPARE(iarToolchain->detection(), ToolChain::UninitializedDetection); } -void verifyGccToolchain(const McuToolChainPackage *gccPackage) +void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage) +{ + //Fake register and fake detect compiler. + ProjectExplorer::ToolChainFactory toolchainFactory; + Id armGccId{ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID}; + + ToolChain *armToolchain{toolchainFactory.createToolChain(armGccId)}; + armToolchain->setLanguage(cxxLanguageId); + ToolChainManager::instance()->registerToolChain(armToolchain); + + QVERIFY(armGccPackage != nullptr); + QCOMPARE(armGccPackage->cmakeVariableName(), Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE); + QCOMPARE(armGccPackage->environmentVariableName(), armGccEnvVar); + QCOMPARE(armGccPackage->isDesktopToolchain(), false); + QCOMPARE(armGccPackage->toolChainName(), armGcc); + QCOMPARE(armGccPackage->toolchainType(), McuToolChainPackage::ToolChainType::ArmGcc); + QCOMPARE(armGccPackage->settingsKey(), armGccDirectorySetting); + + // FIXME(piotr.mucko): Re-enable when toolchains retrieval from McuToolChainPackage is unified for arm and iar. + // armToolchain = armGccPackage->toolChain(cxxLanguageId); + // QVERIFY(armToolchain != nullptr); +} + +void verifyGccToolchain(const McuToolChainPackagePtr &gccPackage) { QVERIFY(gccPackage != nullptr); - QCOMPARE(gccPackage->cmakeToolChainFileName(), QString{unsupported}.append(cmakeExtension)); QCOMPARE(gccPackage->cmakeVariableName(), ""); QCOMPARE(gccPackage->environmentVariableName(), ""); QCOMPARE(gccPackage->isDesktopToolchain(), true); @@ -143,25 +189,71 @@ void verifyGccToolchain(const McuToolChainPackage *gccPackage) QCOMPARE(gccPackage->toolchainType(), McuToolChainPackage::ToolChainType::GCC); } +void verifyTargetToolchains(const Targets &targets, + const QString &toolchainFilePath, + const QString &compilerPath, + const QString &compilerSetting) +{ + QCOMPARE(targets.size(), 1); + const auto &target{targets.first()}; + + const auto toolchainFile{target->toolChainFilePackage()}; + QVERIFY(toolchainFile); + QCOMPARE(toolchainFile->cmakeVariableName(), Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE); + QCOMPARE(toolchainFile->settingsKey(), empty); + QCOMPARE(toolchainFile->path().toString(), toolchainFilePath); + + const auto toolchainCompiler{target->toolChainPackage()}; + QVERIFY(toolchainCompiler); + QCOMPARE(toolchainCompiler->cmakeVariableName(), Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE); + QCOMPARE(toolchainCompiler->path().toUserOutput(), compilerPath); + QCOMPARE(toolchainCompiler->settingsKey(), compilerSetting); +} + McuSupportTest::McuSupportTest() : targetFactory{settingsMockPtr} - , toolchainPackagePtr{ - new McuToolChainPackage{settingsMockPtr, - {}, // label - {}, // defaultPath - {}, // detectionPath - {}, // settingsKey - McuToolChainPackage::ToolChainType::Unsupported, // toolchain type - {}, // cmake var name - {}}} // env var name -{} + , toolchainPackagePtr{new McuToolChainPackage{ + settingsMockPtr, + {}, // label + {}, // defaultPath + {}, // detectionPath + {}, // settingsKey + McuToolChainPackage::ToolChainType::Unsupported, // toolchain type + {}, // cmake var name + {}}} // env var name + , armGccToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr, + armGccLabel, + armGccDir, + {}, // validation path + armGccDirectorySetting, + McuToolChainPackage::ToolChainType::ArmGcc, + Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, + armGccEnvVar}} + , iarToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr, + iarLabel, + iarDir, + {}, // validation path + iarSetting, + McuToolChainPackage::ToolChainType::IAR, + Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, + iarEnvVar}} + , platform{id, name, vendor} + , mcuTarget{currentQulVersion, + platform, + McuTarget::OS::FreeRTOS, + {sdkPackagePtr, freeRtosPackagePtr}, + armGccToolchainPackagePtr, + armGccToolchainFilePackagePtr} +{ + testing::Mock::AllowLeak(settingsMockPtr.get()); +} void McuSupportTest::initTestCase() { targetDescription = Sdk::McuTargetDescription{ "2.0.1", "2", - platform, + platformDescription, Sdk::McuTargetDescription::Toolchain{}, Sdk::McuTargetDescription::BoardSdk{}, Sdk::McuTargetDescription::FreeRTOS{}, @@ -172,19 +264,31 @@ void McuSupportTest::initTestCase() EXPECT_CALL(*freeRtosPackage, cmakeVariableName()) .WillRepeatedly(Return(QString{freeRtosCMakeVar})); EXPECT_CALL(*freeRtosPackage, isValidStatus()).WillRepeatedly(Return(true)); - EXPECT_CALL(*freeRtosPackage, path()) - .WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath))); + EXPECT_CALL(*freeRtosPackage, path()).WillRepeatedly(Return(FilePath::fromString(freeRtosPath))); EXPECT_CALL(*freeRtosPackage, isAddToSystemPath()).WillRepeatedly(Return(true)); - EXPECT_CALL(*freeRtosPackage, detectionPath()).WillRepeatedly(Return(Utils::FilePath{})); + EXPECT_CALL(*freeRtosPackage, detectionPath()).WillRepeatedly(Return(FilePath{})); - EXPECT_CALL(*sdkPackage, environmentVariableName()) - .WillRepeatedly(Return(QString{freeRtosEnvVar})); - EXPECT_CALL(*sdkPackage, cmakeVariableName()).WillRepeatedly(Return(QString{freeRtosCMakeVar})); + EXPECT_CALL(*sdkPackage, environmentVariableName()).WillRepeatedly(Return(QString{qulEnvVar})); + EXPECT_CALL(*sdkPackage, cmakeVariableName()).WillRepeatedly(Return(QString{qulCmakeVar})); EXPECT_CALL(*sdkPackage, isValidStatus()).WillRepeatedly(Return(true)); - EXPECT_CALL(*sdkPackage, path()) - .WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath))); + EXPECT_CALL(*sdkPackage, path()).WillRepeatedly(Return(FilePath::fromString(qtForMcuSdkPath))); EXPECT_CALL(*sdkPackage, isAddToSystemPath()).WillRepeatedly(Return(true)); - EXPECT_CALL(*sdkPackage, detectionPath()).WillRepeatedly(Return(Utils::FilePath{})); + EXPECT_CALL(*sdkPackage, detectionPath()).WillRepeatedly(Return(FilePath{})); + + EXPECT_CALL(*armGccToolchainFilePackage, environmentVariableName()) + .WillRepeatedly(Return(QString{QString{}})); + EXPECT_CALL(*armGccToolchainFilePackage, cmakeVariableName()) + .WillRepeatedly(Return(QString{Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE})); + EXPECT_CALL(*armGccToolchainFilePackage, isValidStatus()).WillRepeatedly(Return(true)); + EXPECT_CALL(*armGccToolchainFilePackage, path()) + .WillRepeatedly(Return(FilePath::fromString(armGccToolchainFilePath))); + EXPECT_CALL(*armGccToolchainFilePackage, isAddToSystemPath()).WillRepeatedly(Return(false)); + EXPECT_CALL(*armGccToolchainFilePackage, detectionPath()).WillRepeatedly(Return(FilePath{})); + + ON_CALL(*settingsMockPtr, getPath) + .WillByDefault([](const QString &, QSettings::Scope, const FilePath &m_defaultPath) { + return m_defaultPath; + }); } void McuSupportTest::test_parseBasicInfoFromJson() @@ -204,67 +308,56 @@ void McuSupportTest::test_parseCmakeEntries() QCOMPARE(freeRtosPackage.envVar, nxp1064FreeRtosEnvVar); } +void McuSupportTest::test_parseToolchainFromJSON_data() +{ + QTest::addColumn("json"); + QTest::addColumn("environmentVariable"); + QTest::addColumn("label"); + QTest::addColumn("toolchainFile"); + QTest::addColumn("id"); + + //TODO(me): Add ghs nxp 1064 nxp 1070. + QTest::newRow("armgcc_nxp_1050_json") + << armgcc_nxp_1050_json << armGccEnvVar << armGccLabel << armGccToolchainFilePath << armGcc; + QTest::newRow("armgcc_stm32f769i_freertos_json") + << armgcc_stm32f769i_freertos_json << armGccEnvVar << armGccLabel << armGccToolchainFilePath + << armGcc; + + QTest::newRow("armgcc_stm32h750b_metal_json") + << armgcc_stm32h750b_metal_json << armGccEnvVar << armGccLabel << armGccToolchainFilePath + << armGcc; + + QTest::newRow("armgcc_nxp_mimxrt1170_evk_freertos_json") + << armgcc_nxp_mimxrt1170_evk_freertos_json << armGccEnvVar << armGccLabel + << armGccToolchainFilePath << armGcc; + + QTest::newRow("iar_stm32f469i_metal_json") + << iar_stm32f469i_metal_json << iarEnvVar << iarLabel << iarToolchainFilePath << iar; +} + void McuSupportTest::test_parseToolchainFromJSON() { - Sdk::McuTargetDescription description{Sdk::parseDescriptionJson(iar_stm32f469i_metal_json)}; - QCOMPARE(description.toolchain.id, iar); - QCOMPARE(description.toolchain.packages.size(), 2); + QFETCH(QString, json); + QFETCH(QString, environmentVariable); + QFETCH(QString, label); + QFETCH(QString, toolchainFile); + QFETCH(QString, id); + Sdk::McuTargetDescription description{Sdk::parseDescriptionJson(json.toLocal8Bit())}; + QCOMPARE(description.toolchain.id, id); - const Sdk::PackageDescription &compilerPackage{description.toolchain.packages.at(0)}; + const Sdk::PackageDescription &compilerPackage{description.toolchain.compiler}; QCOMPARE(compilerPackage.cmakeVar, Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE); - QCOMPARE(compilerPackage.envVar, iarEnvVar); + QCOMPARE(compilerPackage.envVar, environmentVariable); - const Sdk::PackageDescription &toolchainFilePackage{description.toolchain.packages.at(1)}; + const Sdk::PackageDescription &toolchainFilePackage{description.toolchain.file}; QCOMPARE(toolchainFilePackage.label, cmakeToolchainLabel); QCOMPARE(toolchainFilePackage.envVar, QString{}); QCOMPARE(toolchainFilePackage.cmakeVar, Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE); - QCOMPARE(toolchainFilePackage.defaultPath, "$Qul_ROOT/lib/cmake/Qul/toolchain/iar.cmake"); -} - -void McuSupportTest::test_addNewKit() -{ - const QString cmakeVar = "CMAKE_SDK"; - EXPECT_CALL(*sdkPackage, cmakeVariableName()).WillRepeatedly(Return(cmakeVar)); - Kit kit; - - const McuTarget::Platform platform{id, name, vendor}; - McuTarget mcuTarget{currentQulVersion, // version - platform, // platform - McuTarget::OS::FreeRTOS, // os - {sdkPackagePtr, freeRtosPackagePtr}, // packages - toolchainPackagePtr}; // toolchain packages - - auto &kitManager{*KitManager::instance()}; - - QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded); - - auto *newKit{McuKitManager::newKit(&mcuTarget, sdkPackagePtr)}; - QVERIFY(newKit != nullptr); - - QCOMPARE(kitAddedSpy.count(), 1); - QList arguments = kitAddedSpy.takeFirst(); - auto *createdKit = qvariant_cast(arguments.at(0)); - QVERIFY(createdKit != nullptr); - QCOMPARE(createdKit, newKit); - - const auto config = CMakeConfigurationKitAspect::configuration(newKit); - QVERIFY(config.size() > 0); - QVERIFY(Utils::indexOf(config.toVector(), - [&cmakeVar](const CMakeConfigItem &item) { - return item.key == cmakeVar.toUtf8(); - }) - != -1); + QCOMPARE(toolchainFilePackage.defaultPath.cleanPath().toUserOutput(), toolchainFile); } void McuSupportTest::test_addFreeRtosCmakeVarToKit() { - Kit kit; - const McuTarget::Platform platform{id, name, vendor}; - McuTarget mcuTarget{currentQulVersion, - platform, - McuTarget::OS::FreeRTOS, - {sdkPackagePtr, freeRtosPackagePtr}, - toolchainPackagePtr}; McuKitManager::upgradeKitInPlace(&kit, &mcuTarget, sdkPackagePtr); QVERIFY(kit.hasValue(EnvironmentKitAspect::id())); @@ -273,65 +366,65 @@ void McuSupportTest::test_addFreeRtosCmakeVarToKit() const auto &cmakeConfig{CMakeConfigurationKitAspect::configuration(&kit)}; QVERIFY(cmakeConfig.size() > 0); - - CMakeConfigItem - expectedCmakeVar{freeRtosCMakeVar, - FilePath::fromString(defaultfreeRtosPath).toUserOutput().toLocal8Bit()}; - QVERIFY(cmakeConfig.contains(expectedCmakeVar)); + QCOMPARE(cmakeConfig.valueOf(freeRtosCMakeVar), + FilePath::fromString(freeRtosPath).toString().toLocal8Bit()); } void McuSupportTest::test_legacy_createIarToolchain() { McuToolChainPackagePtr iarToolchainPackage = Sdk::createIarToolChainPackage(settingsMockPtr); - verifyIarToolchain(iarToolchainPackage.get()); + verifyIarToolchain(iarToolchainPackage); } void McuSupportTest::test_createIarToolchain() { const auto description = Sdk::parseDescriptionJson(iar_stm32f469i_metal_json); - McuToolChainPackage *iarToolchainPackage{targetFactory.createToolchain(description.toolchain)}; + McuToolChainPackagePtr iarToolchainPackage{targetFactory.createToolchain(description.toolchain)}; verifyIarToolchain(iarToolchainPackage); } void McuSupportTest::test_legacy_createDesktopGccToolchain() { McuToolChainPackagePtr gccPackage = Sdk::createGccToolChainPackage(settingsMockPtr); - verifyGccToolchain(gccPackage.get()); + verifyGccToolchain(gccPackage); } void McuSupportTest::test_createDesktopGccToolchain() { const auto description = Sdk::parseDescriptionJson(gcc_desktop_json); - McuToolChainPackage *gccPackage{targetFactory.createToolchain(description.toolchain)}; + McuToolChainPackagePtr gccPackage{targetFactory.createToolchain(description.toolchain)}; verifyGccToolchain(gccPackage); } -void McuSupportTest::test_skipTargetCreationWhenToolchainInfoIsMissing() +void McuSupportTest::test_verifyManuallyCreatedArmGccToolchain() { - const auto [targets, packages]{targetFactory.createTargets(targetDescription)}; - QVERIFY(targets.isEmpty()); + verifyArmGccToolchain(armGccToolchainPackagePtr); } -void McuSupportTest::test_returnNullWhenCreatingToolchainIfInfoIsMissing() +void McuSupportTest::test_legacy_createArmGccToolchain() { - Sdk::McuTargetDescription::Toolchain toolchainDescription{}; - toolchainDescription.id = iar; - McuToolChainPackage *toolchain{targetFactory.createToolchain(toolchainDescription)}; - QCOMPARE(toolchain, nullptr); + McuToolChainPackagePtr armGccPackage = Sdk::createArmGccToolchainPackage(settingsMockPtr); + verifyArmGccToolchain(armGccPackage); } -void McuSupportTest::test_returnNullWhenCreatingToolchainIfIdIsEmpty() +void McuSupportTest::test_createArmGccToolchain_data() { - McuToolChainPackage *toolchain{targetFactory.createToolchain({})}; - QCOMPARE(toolchain, nullptr); + QTest::addColumn("json"); + QTest::newRow("armgcc_nxp_1050_json") << armgcc_nxp_1050_json; + QTest::newRow("armgcc_stm32f769i_freertos_json") << armgcc_stm32f769i_freertos_json; + QTest::newRow("armgcc_stm32h750b_metal_json") << armgcc_stm32h750b_metal_json; + QTest::newRow("armgcc_nxp_mimxrt1170_evk_freertos_json") + << armgcc_nxp_mimxrt1170_evk_freertos_json; } -void McuSupportTest::test_defaultToolchainPackageCtorShouldReturnDefaultToolchainFileName() +void McuSupportTest::test_createArmGccToolchain() { - QVERIFY(!toolchainPackagePtr->cmakeToolChainFileName().isEmpty()); - QCOMPARE(toolchainPackagePtr->cmakeToolChainFileName(), - QString{unsupported}.append(cmakeExtension)); + QFETCH(QString, json); + + const auto description = Sdk::parseDescriptionJson(json.toLocal8Bit()); + McuToolChainPackagePtr armGccPackage{targetFactory.createToolchain(description.toolchain)}; + verifyArmGccToolchain(armGccPackage); } void McuSupportTest::test_mapParsedToolchainIdToCorrespondingType_data() @@ -358,16 +451,12 @@ void McuSupportTest::test_mapParsedToolchainIdToCorrespondingType() QCOMPARE(toolchain->toolchainType(), toolchainType); } -void McuSupportTest::test_createPackagesWithCorrespondingSettings_data() +void McuSupportTest::test_legacy_createPackagesWithCorrespondingSettings_data() { QTest::addColumn("json"); QTest::addColumn>("expectedSettings"); QSet commonSettings{{"CypressAutoFlashUtil"}, - {"GHSArmToolchain"}, - {"GHSToolchain"}, - {"GNUArmEmbeddedToolchain"}, - {"IARToolchain"}, {"MCUXpressoIDE"}, {"RenesasFlashProgrammer"}, {"Stm32CubeProgrammer"}}; @@ -375,33 +464,40 @@ void McuSupportTest::test_createPackagesWithCorrespondingSettings_data() QTest::newRow("nxp1064") << iar_nxp_1064_json << QSet{{"EVK_MIMXRT1064_SDK_PATH"}, {QString{Constants::SETTINGS_KEY_FREERTOS_PREFIX} - .append("IMXRT1064")}} + .append("IMXRT1064")}, + "IARToolchain"} .unite(commonSettings); + QTest::newRow("stm32f469i") << iar_stm32f469i_metal_json + << QSet{{"STM32Cube_FW_F4_SDK_PATH"}, "IARToolchain"}.unite( + commonSettings); QTest::newRow("nxp1050") << armgcc_nxp_1050_json << QSet{{"EVKB_IMXRT1050_SDK_PATH"}, {QString{Constants::SETTINGS_KEY_FREERTOS_PREFIX} - .append("IMXRT1050")}} + .append("IMXRT1050")}, + "GNUArmEmbeddedToolchain"} .unite(commonSettings); - QTest::newRow("stm32h750b") << armgcc_stm32h750b_metal_json - << QSet{{"STM32Cube_FW_H7_SDK_PATH"}}.unite(commonSettings); - + << QSet{{"STM32Cube_FW_H7_SDK_PATH"}, + "GNUArmEmbeddedToolchain"} + .unite(commonSettings); QTest::newRow("stm32f769i") << armgcc_stm32f769i_freertos_json - << QSet{{"STM32Cube_FW_F7_SDK_PATH"}}.unite(commonSettings); + << QSet{{"STM32Cube_FW_F7_SDK_PATH"}, + "GNUArmEmbeddedToolchain"} + .unite(commonSettings); - QTest::newRow("stm32f469i") << iar_stm32f469i_metal_json - << QSet{{"STM32Cube_FW_F4_SDK_PATH"}}.unite(commonSettings); + QTest::newRow("ghs_rh850_d1m1a_baremetal_json") + << ghs_rh850_d1m1a_baremetal_json << QSet{"GHSToolchain"}.unite(commonSettings); } -void McuSupportTest::test_createPackagesWithCorrespondingSettings() +void McuSupportTest::test_legacy_createPackagesWithCorrespondingSettings() { QFETCH(QString, json); const Sdk::McuTargetDescription description = Sdk::parseDescriptionJson(json.toLocal8Bit()); - const auto [targets, - packages]{Sdk::targetsFromDescriptions({description}, settingsMockPtr, runLegacy)}; + const auto [targets, packages]{ + Sdk::targetsFromDescriptions({description}, settingsMockPtr, qtForMcuSdkPath, runLegacy)}; Q_UNUSED(targets); - QSet settings = Utils::transform>(packages, [](const auto &package) { + QSet settings = transform>(packages, [](const auto &package) { return package->settingsKey(); }); QFETCH(QSet, expectedSettings); @@ -440,30 +536,26 @@ void McuSupportTest::test_createTargets() Sdk::PackageDescription packageDescription{id, nxp1064FreeRtosEnvVar, freeRtosCMakeVar, - "setting", - "Freertos directory", - "/opt/freertos/1064", + freeRtosSetting, + freeRtosDescription, + freeRtosPath, "", {}, true}; targetDescription.freeRTOS.packages.append(packageDescription); - targetDescription.toolchain.id = armgcc; - targetDescription.toolchain.packages.append(Sdk::PackageDescription{}); + targetDescription.toolchain.id = armGcc; - const auto [targets, packages]{targetFactory.createTargets(targetDescription)}; + const auto [targets, packages]{targetFactory.createTargets(targetDescription, qtForMcuSdkPath)}; QVERIFY(!targets.empty()); - const McuTargetPtr target{*targets.constBegin()}; + const McuTargetPtr target{targets.at(0)}; QCOMPARE(target->colorDepth(), colorDepth); const auto &tgtPackages{target->packages()}; QVERIFY(!tgtPackages.empty()); - // for whatever reasons there are more than a single package, get the right one to check - const auto rtosPackage - = Utils::findOrDefault(tgtPackages, - [id = QString::fromLatin1(id)](McuPackagePtr pkg) { - return pkg->label() == id; - }); - QVERIFY(rtosPackage); - QCOMPARE(rtosPackage->environmentVariableName(), nxp1064FreeRtosEnvVar); + + QVERIFY(anyOf(tgtPackages, [](const McuPackagePtr &pkg) { + return (pkg->environmentVariableName() == nxp1064FreeRtosEnvVar + && pkg->cmakeVariableName() == freeRtosCMakeVar && pkg->label() == id); + })); } void McuSupportTest::test_createPackages() @@ -471,9 +563,9 @@ void McuSupportTest::test_createPackages() Sdk::PackageDescription packageDescription{id, nxp1064FreeRtosEnvVar, freeRtosCMakeVar, - "Freertos directory", - "setting", - "/opt/freertos/1064", + freeRtosLabel, + freeRtosSetting, + freeRtosPath, "", {}, true}; @@ -483,7 +575,7 @@ void McuSupportTest::test_createPackages() QVERIFY(!packages.empty()); } -void McuSupportTest::test_removeRtosSuffix_data() +void McuSupportTest::test_removeRtosSuffixFromEnvironmentVariable_data() { QTest::addColumn("freeRtosEnvVar"); QTest::addColumn("expectedEnvVarWithoutSuffix"); @@ -494,14 +586,14 @@ void McuSupportTest::test_removeRtosSuffix_data() QTest::newRow("stm32f7") << stm32f7FreeRtosEnvVar << stm32f7; } -void McuSupportTest::test_removeRtosSuffix() +void McuSupportTest::test_removeRtosSuffixFromEnvironmentVariable() { QFETCH(QString, freeRtosEnvVar); QFETCH(QString, expectedEnvVarWithoutSuffix); QCOMPARE(removeRtosSuffix(freeRtosEnvVar), expectedEnvVarWithoutSuffix); } -void McuSupportTest::test_2dot1UsesLegacyImplementation() +void McuSupportTest::test_twoDotOneUsesLegacyImplementation() { QCOMPARE(McuSupportOptions::isLegacyVersion({2, 1}), true); QCOMPARE(McuSupportOptions::isLegacyVersion({2, 0}), true); @@ -511,4 +603,144 @@ void McuSupportTest::test_2dot1UsesLegacyImplementation() QCOMPARE(McuSupportOptions::isLegacyVersion({2, 2, 1}), false); } +void McuSupportTest::test_addNewKit() +{ + const QString cmakeVar = "CMAKE_SDK"; + EXPECT_CALL(*sdkPackage, cmakeVariableName()).WillRepeatedly(Return(cmakeVar)); + + auto &kitManager{*KitManager::instance()}; + + QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded); + + auto *newKit{McuKitManager::newKit(&mcuTarget, sdkPackagePtr)}; + QVERIFY(newKit != nullptr); + + QCOMPARE(kitAddedSpy.count(), 1); + QList arguments = kitAddedSpy.takeFirst(); + auto *createdKit = qvariant_cast(arguments.at(0)); + QVERIFY(createdKit != nullptr); + QCOMPARE(createdKit, newKit); + + const auto config = CMakeConfigurationKitAspect::configuration(newKit); + QVERIFY(config.size() > 0); + QVERIFY( + indexOf(config.toVector(), + [&cmakeVar](const CMakeConfigItem &item) { return item.key == cmakeVar.toUtf8(); }) + != -1); +} + +void McuSupportTest::test_getFullToolchainFilePathFromTarget() +{ + QCOMPARE(mcuTarget.toolChainFilePackage()->path().toUserOutput(), + armGccToolchainFilePackagePtr->path().toUserOutput()); +} + +void McuSupportTest::test_legacy_getPredefinedToolchainFilePackage() +{ + QHash toolchainCreators{ + {armGcc, [this] { return armGccToolchainPackagePtr; }}}; + McuTargetFactoryLegacy legacyTargetFactory{toolchainCreators, + {{armGcc, armGccToolchainFilePackagePtr}}, + {}, + settingsMockPtr}; + auto armToolchainFile = legacyTargetFactory.getToolchainFile(qtForMcuSdkPath, armGcc); + QVERIFY(armToolchainFile); + QCOMPARE(armToolchainFile, armGccToolchainFilePackagePtr); +} + +void McuSupportTest::test_legacy_createUnsupportedToolchainFilePackage() +{ + QHash toolchainCreators{ + {armGcc, [this] { return armGccToolchainPackagePtr; }}}; + McuTargetFactoryLegacy legacyTargetFactory{toolchainCreators, + {{armGcc, armGccToolchainFilePackagePtr}}, + {}, + settingsMockPtr}; + + auto unsupportedToolchainFile = legacyTargetFactory.getToolchainFile(qtForMcuSdkPath, iar); + QVERIFY(unsupportedToolchainFile); + QCOMPARE(unsupportedToolchainFile->path().toUserOutput(), unsupportedToolchainFilePath); + QCOMPARE(unsupportedToolchainFile->cmakeVariableName(), + Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE); +} + +void McuSupportTest::test_legacy_createTargetWithToolchainPackages_data() +{ + QTest::addColumn("json"); + QTest::addColumn("toolchainFilePath"); + QTest::addColumn("compilerPath"); + QTest::addColumn("compilerSetting"); + + QTest::newRow("nxp1050") << armgcc_nxp_1050_json << armGccToolchainFilePath << armGccDir + << armGccDirectorySetting; + QTest::newRow("stm32h750b") << armgcc_stm32h750b_metal_json << armGccToolchainFilePath + << armGccDir << armGccDirectorySetting; + QTest::newRow("stm32f769i") << armgcc_stm32f769i_freertos_json << armGccToolchainFilePath + << armGccDir << armGccDirectorySetting; + QTest::newRow("stm32f469i") << iar_stm32f469i_metal_json << iarToolchainFilePath << iarDir + << iarSetting; + QTest::newRow("nxp1064") << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting; + QTest::newRow("nxp1064") << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting; + QTest::newRow("ghs_rh850_d1m1a_baremetal_json") + << ghs_rh850_d1m1a_baremetal_json << greenhillToolchainFilePath << greenhillCompilerDir + << greenhillSetting; +} + +void McuSupportTest::test_legacy_createTargetWithToolchainPackages() +{ + QFETCH(QString, json); + QFETCH(QString, toolchainFilePath); + QFETCH(QString, compilerPath); + QFETCH(QString, compilerSetting); + + const Sdk::McuTargetDescription description = Sdk::parseDescriptionJson(json.toLocal8Bit()); + + EXPECT_CALL(*settingsMockPtr, + getPath(QString{Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK}, _, _)) + .WillRepeatedly(Return(FilePath::fromString(qtForMcuSdkPath))); + EXPECT_CALL(*settingsMockPtr, getPath(compilerSetting, _, _)) + .WillRepeatedly(Return(FilePath::fromString(compilerPath))); + + const auto [targets, packages]{ + Sdk::targetsFromDescriptions({description}, settingsMockPtr, qtForMcuSdkPath, runLegacy)}; + Q_UNUSED(packages); + + verifyTargetToolchains(targets, toolchainFilePath, compilerPath, compilerSetting); +} + +void McuSupportTest::test_createTargetWithToolchainPackages_data() +{ + test_legacy_createTargetWithToolchainPackages_data(); +} + +void McuSupportTest::test_createTargetWithToolchainPackages() +{ + QFETCH(QString, json); + QFETCH(QString, toolchainFilePath); + QFETCH(QString, compilerPath); + QFETCH(QString, compilerSetting); + + EXPECT_CALL(*settingsMockPtr, getPath(compilerSetting, _, _)) + .WillRepeatedly(Return(FilePath::fromString(compilerPath))); + + const Sdk::McuTargetDescription description = Sdk::parseDescriptionJson(json.toLocal8Bit()); + const auto [targets, packages]{ + Sdk::targetsFromDescriptions({description}, settingsMockPtr, qtForMcuSdkPath, !runLegacy)}; + Q_UNUSED(packages); + + verifyTargetToolchains(targets, toolchainFilePath, compilerPath, compilerSetting); +} + +void McuSupportTest::test_addToolchainFileInfoToKit() +{ + McuKitManager::upgradeKitInPlace(&kit, &mcuTarget, sdkPackagePtr); + + QVERIFY(kit.isValid()); + QCOMPARE(kit.value(Constants::KIT_MCUTARGET_TOOLCHAIN_KEY).toString(), armGcc); + + const auto &cmakeConfig{CMakeConfigurationKitAspect::configuration(&kit)}; + QVERIFY(!cmakeConfig.empty()); + QCOMPARE(cmakeConfig.valueOf(Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE), armGccToolchainFilePath); +} + } // namespace McuSupport::Internal::Test diff --git a/src/plugins/mcusupport/test/unittest.h b/src/plugins/mcusupport/test/unittest.h index 0e95ba6baa0..4cacb680ec3 100644 --- a/src/plugins/mcusupport/test/unittest.h +++ b/src/plugins/mcusupport/test/unittest.h @@ -25,20 +25,13 @@ #pragma once -#include "mcupackage.h" -#include "mcusupportoptions.h" -#include "mcusupportplugin.h" -#include "mcusupportsdk.h" #include "mcutarget.h" #include "mcutargetfactory.h" #include "packagemock.h" #include "settingshandlermock.h" #include -#include -#include -#include -#include + #include #include #include @@ -48,6 +41,7 @@ namespace McuSupport::Internal::Test { class McuSupportTest : public QObject { Q_OBJECT + public: McuSupportTest(); @@ -57,17 +51,19 @@ private slots: void test_addNewKit(); void test_parseBasicInfoFromJson(); void test_parseCmakeEntries(); + void test_parseToolchainFromJSON_data(); void test_parseToolchainFromJSON(); void test_mapParsedToolchainIdToCorrespondingType_data(); void test_mapParsedToolchainIdToCorrespondingType(); - void test_defaultToolchainPackageCtorShouldReturnDefaultToolchainFileName(); - void test_createPackagesWithCorrespondingSettings(); - void test_createPackagesWithCorrespondingSettings_data(); + void test_legacy_createPackagesWithCorrespondingSettings(); + void test_legacy_createPackagesWithCorrespondingSettings_data(); + void test_legacy_createTargetWithToolchainPackages_data(); + void test_legacy_createTargetWithToolchainPackages(); + void test_createTargetWithToolchainPackages_data(); + void test_createTargetWithToolchainPackages(); + void test_createFreeRtosPackageWithCorrectSetting_data(); void test_createFreeRtosPackageWithCorrectSetting(); - void test_skipTargetCreationWhenToolchainInfoIsMissing(); - void test_returnNullWhenCreatingToolchainIfInfoIsMissing(); - void test_returnNullWhenCreatingToolchainIfIdIsEmpty(); void test_createTargets(); void test_createPackages(); void test_addFreeRtosCmakeVarToKit(); @@ -75,9 +71,18 @@ private slots: void test_createIarToolchain(); void test_legacy_createDesktopGccToolchain(); void test_createDesktopGccToolchain(); - void test_removeRtosSuffix_data(); - void test_removeRtosSuffix(); - void test_2dot1UsesLegacyImplementation(); + void test_verifyManuallyCreatedArmGccToolchain(); + void test_legacy_createArmGccToolchain(); + void test_createArmGccToolchain_data(); + void test_createArmGccToolchain(); + void test_removeRtosSuffixFromEnvironmentVariable_data(); + void test_removeRtosSuffixFromEnvironmentVariable(); + + void test_twoDotOneUsesLegacyImplementation(); + void test_addToolchainFileInfoToKit(); + void test_getFullToolchainFilePathFromTarget(); + void test_legacy_getPredefinedToolchainFilePackage(); + void test_legacy_createUnsupportedToolchainFilePackage(); private: QVersionNumber currentQulVersion{2, 0}; @@ -86,11 +91,17 @@ private: McuPackagePtr freeRtosPackagePtr{freeRtosPackage}; McuPackagePtr sdkPackagePtr{sdkPackage}; - SettingsHandlerMock *settingsMock{new SettingsHandlerMock}; - QSharedPointer settingsMockPtr{settingsMock}; - Sdk::McuTargetFactory targetFactory; + QSharedPointer settingsMockPtr{new SettingsHandlerMock}; + McuTargetFactory targetFactory; Sdk::McuTargetDescription targetDescription; McuToolChainPackagePtr toolchainPackagePtr; + McuToolChainPackagePtr armGccToolchainPackagePtr; + McuToolChainPackagePtr iarToolchainPackagePtr; + PackageMock *armGccToolchainFilePackage{new PackageMock}; + McuPackagePtr armGccToolchainFilePackagePtr{armGccToolchainFilePackage}; + McuTarget::Platform platform; + McuTarget mcuTarget; + ProjectExplorer::Kit kit; }; // class McuSupportTest } // namespace McuSupport::Internal::Test