From 3c3ea74ca2c947c6cf0e93cabc5cd627b6cd6b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Mu=C4=87ko?= Date: Mon, 25 Apr 2022 19:52:29 +0200 Subject: [PATCH] McuSupport: Separate toolchain file and compiler packages Toolchain package represents information about compiler and toolchain file (.cmake). This information is parsed from JSON and used for Kit creation. This includes cmake variables, path to compiler. This patch extracts information about toolchain file into separate McuPackage. Change-Id: Id165bdc5afa5d7cf5b5c96620e11cb878254c181 Reviewed-by: Reviewed-by: Alessandro Portale --- .../mcusupport/mcuabstracttargetfactory.h | 10 +- src/plugins/mcusupport/mcukitmanager.cpp | 12 +- src/plugins/mcusupport/mculegacyconstants.h | 33 ++ src/plugins/mcusupport/mcupackage.cpp | 5 - src/plugins/mcusupport/mcupackage.h | 1 - src/plugins/mcusupport/mcusupportconstants.h | 2 +- src/plugins/mcusupport/mcusupportsdk.cpp | 124 +++- src/plugins/mcusupport/mcusupportsdk.h | 9 +- src/plugins/mcusupport/mcutarget.cpp | 7 + src/plugins/mcusupport/mcutarget.h | 3 + src/plugins/mcusupport/mcutargetdescription.h | 3 +- src/plugins/mcusupport/mcutargetfactory.cpp | 30 +- src/plugins/mcusupport/mcutargetfactory.h | 9 +- .../mcusupport/mcutargetfactorylegacy.cpp | 60 +- .../mcusupport/mcutargetfactorylegacy.h | 22 +- .../mcusupport/test/armgcc_nxp_1050_json.h | 9 +- .../armgcc_nxp_mimxrt1170_evk_freertos_json.h | 114 ++++ .../test/armgcc_stm32f769i_freertos_json.h | 8 +- .../test/armgcc_stm32h750b_metal_json.h | 8 +- .../test/ghs_rh850_d1m1a_baremetal_json.h | 87 +++ .../mcusupport/test/iar_nxp_1064_json.h | 23 +- .../test/iar_stm32f469i_metal_json.h | 8 +- src/plugins/mcusupport/test/unittest.cpp | 548 +++++++++++++----- src/plugins/mcusupport/test/unittest.h | 51 +- 24 files changed, 893 insertions(+), 293 deletions(-) create mode 100644 src/plugins/mcusupport/mculegacyconstants.h create mode 100644 src/plugins/mcusupport/test/armgcc_nxp_mimxrt1170_evk_freertos_json.h create mode 100644 src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h 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