diff --git a/src/plugins/mcusupport/mcuabstractpackage.h b/src/plugins/mcusupport/mcuabstractpackage.h index 8e6c85443e2..eed4132fe8f 100644 --- a/src/plugins/mcusupport/mcuabstractpackage.h +++ b/src/plugins/mcusupport/mcuabstractpackage.h @@ -33,6 +33,8 @@ class FilePath; namespace McuSupport::Internal { +class McuPackageVersionDetector; + class McuAbstractPackage : public QObject { Q_OBJECT @@ -67,6 +69,7 @@ public: virtual bool writeToSettings() const = 0; virtual QWidget *widget() = 0; + virtual const McuPackageVersionDetector *getVersionDetector() const = 0; signals: void changed(); diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 7018da5e6ff..b2ed2aa5e54 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -108,6 +108,11 @@ QStringList McuPackage::versions() const return m_versions; } +const McuPackageVersionDetector *McuPackage::getVersionDetector() const +{ + return m_versionDetector.get(); +} + FilePath McuPackage::basePath() const { return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path; diff --git a/src/plugins/mcusupport/mcupackage.h b/src/plugins/mcusupport/mcupackage.h index 70ac9a4cc64..b1533f140aa 100644 --- a/src/plugins/mcusupport/mcupackage.h +++ b/src/plugins/mcusupport/mcupackage.h @@ -48,8 +48,6 @@ class Id; namespace McuSupport { namespace Internal { -class McuPackageVersionDetector; - class McuPackage : public McuAbstractPackage { Q_OBJECT @@ -90,6 +88,7 @@ public: bool writeToSettings() const override; QWidget *widget() override; + const McuPackageVersionDetector *getVersionDetector() const override; private: void updatePath(); @@ -116,9 +115,9 @@ private: const bool m_addToSystemPath; Status m_status = Status::InvalidPath; -}; +}; // class McuPackage -class McuToolChainPackage : public McuPackage +class McuToolChainPackage final : public McuPackage { Q_OBJECT public: @@ -132,8 +131,8 @@ public: ToolChainType toolchainType, const QStringList &versions, const QString &cmakeVarName, - const QString &envVarName = {}, - const McuPackageVersionDetector *versionDetector = nullptr); + const QString &envVarName, + const McuPackageVersionDetector *versionDetector); ToolChainType toolchainType() const; bool isDesktopToolchain() const; diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 53fc8caac0d..d654c4622c3 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -107,9 +107,6 @@ static McuPackageVersionDetector *generatePackageVersionDetector(const QString & return nullptr; } -/// Create the McuPackage by checking the "boardSdk" property in the JSON file for the board. -/// The name of the environment variable pointing to the the SDK for the board will be defined in the "envVar" property -/// inside the "boardSdk". McuPackagePtr createBoardSdkPackage(const SettingsHandler::Ptr &settingsHandler, const McuTargetDescription &desc) { @@ -191,22 +188,47 @@ McuPackagePtr createUnsupportedToolChainFilePackage(const SettingsHandler::Ptr & McuToolChainPackagePtr createUnsupportedToolChainPackage(const SettingsHandler::Ptr &settingsHandler) { - return McuToolChainPackagePtr{new McuToolChainPackage( - settingsHandler, {}, {}, {}, {}, McuToolChainPackage::ToolChainType::Unsupported, {}, {})}; + return McuToolChainPackagePtr{ + new McuToolChainPackage(settingsHandler, + {}, + {}, + {}, + {}, + McuToolChainPackage::ToolChainType::Unsupported, + {}, + {}, + {}, + nullptr)}; } McuToolChainPackagePtr createMsvcToolChainPackage(const SettingsHandler::Ptr &settingsHandler, const QStringList &versions) { - return McuToolChainPackagePtr{new McuToolChainPackage( - settingsHandler, {}, {}, {}, {}, McuToolChainPackage::ToolChainType::MSVC, versions, {})}; + return McuToolChainPackagePtr{new McuToolChainPackage(settingsHandler, + {}, + {}, + {}, + {}, + McuToolChainPackage::ToolChainType::MSVC, + versions, + {}, + {}, + nullptr)}; } McuToolChainPackagePtr createGccToolChainPackage(const SettingsHandler::Ptr &settingsHandler, const QStringList &versions) { - return McuToolChainPackagePtr{new McuToolChainPackage( - settingsHandler, {}, {}, {}, {}, McuToolChainPackage::ToolChainType::GCC, versions, {})}; + return McuToolChainPackagePtr{new McuToolChainPackage(settingsHandler, + {}, + {}, + {}, + {}, + McuToolChainPackage::ToolChainType::GCC, + versions, + {}, + {}, + nullptr)}; } McuToolChainPackagePtr createArmGccToolchainPackage(const SettingsHandler::Ptr &settingsHandler, @@ -229,10 +251,9 @@ McuToolChainPackagePtr createArmGccToolchainPackage(const SettingsHandler::Ptr & } const Utils::FilePath detectionPath = FilePath("bin/arm-none-eabi-g++").withExecutableSuffix(); - const auto versionDetector - = new McuPackageExecutableVersionDetector(detectionPath, - {"--version"}, - "\\b(\\d+\\.\\d+\\.\\d+)\\b"); + const auto versionDetector = new McuPackageExecutableVersionDetector(detectionPath, + {"--version"}, + R"(\b(\d+\.\d+\.\d+)\b)"); return McuToolChainPackagePtr{ new McuToolChainPackage(settingsHandler, @@ -257,7 +278,7 @@ McuToolChainPackagePtr createGhsToolchainPackage(const SettingsHandler::Ptr &set const auto versionDetector = new McuPackageExecutableVersionDetector(FilePath("as850").withExecutableSuffix(), {"-V"}, - "\\bv(\\d+\\.\\d+\\.\\d+)\\b"); + R"(\bv(\d+\.\d+\.\d+)\b)"); return McuToolChainPackagePtr{ new McuToolChainPackage(settingsHandler, @@ -282,7 +303,7 @@ McuToolChainPackagePtr createGhsArmToolchainPackage(const SettingsHandler::Ptr & const auto versionDetector = new McuPackageExecutableVersionDetector(FilePath("asarm").withExecutableSuffix(), {"-V"}, - "\\bv(\\d+\\.\\d+\\.\\d+)\\b"); + R"(\bv(\d+\.\d+\.\d+)\b)"); return McuToolChainPackagePtr{ new McuToolChainPackage(settingsHandler, @@ -317,10 +338,10 @@ McuToolChainPackagePtr createIarToolChainPackage(const SettingsHandler::Ptr &set } const FilePath detectionPath = FilePath("bin/iccarm").withExecutableSuffix(); - const auto versionDetector + const auto *versionDetector = new McuPackageExecutableVersionDetector(detectionPath, {"--version"}, - "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b"); + R"(\bV(\d+\.\d+\.\d+)\.\d+\b)"); return McuToolChainPackagePtr{ new McuToolChainPackage(settingsHandler, @@ -585,6 +606,19 @@ static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir) return kitsDir.entryInfoList(); } +VersionDetection parseVersionDetection(const QJsonObject &packageEntry) +{ + const QJsonObject versioning = packageEntry.value("versionDetection").toObject(); + return { + versioning["regex"].toString(), + versioning["filePattern"].toString(), + versioning["executableArgs"].toString(), + versioning["xmlElement"].toString(), + versioning["xmlAttribute"].toString(), + versioning["isFile"].toBool(true), + }; +} + static PackageDescription parsePackage(const QJsonObject &cmakeEntry) { const QVariantList versionsVariantList = cmakeEntry["versions"].toArray().toVariantList(); @@ -600,6 +634,7 @@ static PackageDescription parsePackage(const QJsonObject &cmakeEntry) FilePath::fromString(cmakeEntry["defaultValue"].toString()), FilePath::fromString(cmakeEntry["validation"].toString()), versions, + parseVersionDetection(cmakeEntry), false}; } @@ -688,7 +723,7 @@ static const QString legacySupportVersionFor(const QString &sdkVersion) bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message) { - const McuPackagePathVersionDetector versionDetector("(?<=\\bQtMCUs.)(\\d+\\.\\d+)"); + const McuPackagePathVersionDetector versionDetector(R"((?<=\bQtMCUs.)(\d+\.\d+))"); const QString sdkDetectedVersion = versionDetector.parseVersion(qulDir); const QString legacyVersion = legacySupportVersionFor(sdkDetectedVersion); diff --git a/src/plugins/mcusupport/mcusupportversiondetection.cpp b/src/plugins/mcusupport/mcusupportversiondetection.cpp index 2ac9b99c28e..5dcd891d2d6 100644 --- a/src/plugins/mcusupport/mcusupportversiondetection.cpp +++ b/src/plugins/mcusupport/mcusupportversiondetection.cpp @@ -45,12 +45,8 @@ QString matchRegExp(const QString &text, const QString ®Exp) return QString(); } -McuPackageVersionDetector::McuPackageVersionDetector() {} - McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector( - const FilePath &detectionPath, - const QStringList &detectionArgs, - const QString &detectionRegExp) + const FilePath &detectionPath, const QStringList &detectionArgs, const QString &detectionRegExp) : McuPackageVersionDetector() , m_detectionPath(detectionPath) , m_detectionArgs(detectionArgs) @@ -133,7 +129,7 @@ McuPackagePathVersionDetector::McuPackagePathVersionDetector(const QString &vers QString McuPackagePathVersionDetector::parseVersion(const FilePath &packagePath) const { if (!packagePath.exists()) - return QString(); + return {}; return matchRegExp(packagePath.toString(), m_versionRegExp); } diff --git a/src/plugins/mcusupport/mcusupportversiondetection.h b/src/plugins/mcusupport/mcusupportversiondetection.h index 76e88718dbb..e97d941104a 100644 --- a/src/plugins/mcusupport/mcusupportversiondetection.h +++ b/src/plugins/mcusupport/mcusupportversiondetection.h @@ -33,7 +33,7 @@ namespace McuSupport::Internal { class McuPackageVersionDetector { public: - McuPackageVersionDetector(); + McuPackageVersionDetector() = default; virtual ~McuPackageVersionDetector() = default; virtual QString parseVersion(const Utils::FilePath &packagePath) const = 0; }; diff --git a/src/plugins/mcusupport/mcutargetdescription.h b/src/plugins/mcusupport/mcutargetdescription.h index 82f3e77f9ef..83d530706f3 100644 --- a/src/plugins/mcusupport/mcutargetdescription.h +++ b/src/plugins/mcusupport/mcutargetdescription.h @@ -33,6 +33,16 @@ namespace McuSupport::Internal { +struct VersionDetection +{ + QString regex; + QString filePattern; + QString executableArgs; + QString xmlElement; + QString xmlAttribute; + bool isFile; +}; // struct VersionDetection + struct PackageDescription { QString label; @@ -43,6 +53,7 @@ struct PackageDescription Utils::FilePath defaultPath; Utils::FilePath validationPath; QStringList versions; + VersionDetection versionDetection; bool shouldAddToSystemPath; }; //struct PackageDescription diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index fa215617cf5..b759a0e6b92 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -59,6 +59,24 @@ const static QMap toolchainTypeMapp {"ghsarm", McuToolChainPackage::ToolChainType::GHSArm}, }; +McuPackageVersionDetector *createVersionDetection(const VersionDetection &versionDetection) +{ + if (!versionDetection.xmlElement.isEmpty() and !versionDetection.xmlAttribute.isEmpty()) + return new McuPackageXmlVersionDetector{versionDetection.filePattern, + versionDetection.xmlElement, + versionDetection.xmlAttribute, + versionDetection.regex}; + else if (!versionDetection.executableArgs.isEmpty()) + return new McuPackageExecutableVersionDetector{Utils::FilePath::fromString( + versionDetection.filePattern), + QStringList{versionDetection.executableArgs}, + versionDetection.regex}; + else + return new McuPackageDirectoryVersionDetector(versionDetection.filePattern, + versionDetection.regex, + versionDetection.isFile); +} + McuTargetFactory::McuTargetFactory(const SettingsHandler::Ptr &settingsHandler) : settingsHandler{settingsHandler} {} @@ -116,16 +134,16 @@ Packages McuTargetFactory::createPackages(const McuTargetDescription &desc) McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc) { - return McuPackagePtr{new McuPackage{ - settingsHandler, - pkgDesc.label, - pkgDesc.defaultPath, - pkgDesc.validationPath, - pkgDesc.setting, - pkgDesc.cmakeVar, - pkgDesc.envVar, - pkgDesc.versions, - }}; + return McuPackagePtr{new McuPackage{settingsHandler, + pkgDesc.label, + pkgDesc.defaultPath, + pkgDesc.validationPath, + pkgDesc.setting, + pkgDesc.cmakeVar, + pkgDesc.envVar, + pkgDesc.versions, + {}, + createVersionDetection(pkgDesc.versionDetection)}}; } McuToolChainPackage *McuTargetFactory::createToolchain( @@ -144,22 +162,22 @@ McuToolChainPackage *McuTargetFactory::createToolchain( {}, toolchainType, toolchain.versions, - compilerDescription.cmakeVar}; + compilerDescription.cmakeVar, + {}, + nullptr}; else if (!isToolchainDescriptionValid(toolchain)) toolchainType = McuToolChainPackage::ToolChainType::Unsupported; - return new McuToolChainPackage{ - settingsHandler, - compilerDescription.label, - compilerDescription.defaultPath, - compilerDescription.validationPath, - compilerDescription.setting, - toolchainType, - toolchain.versions, - compilerDescription.cmakeVar, - compilerDescription.envVar, - nullptr, // McuPackageVersionDetector - }; + return new McuToolChainPackage{settingsHandler, + compilerDescription.label, + compilerDescription.defaultPath, + compilerDescription.validationPath, + compilerDescription.setting, + toolchainType, + toolchain.versions, + compilerDescription.cmakeVar, + compilerDescription.envVar, + createVersionDetection(compilerDescription.versionDetection)}; } } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcutargetfactory.h b/src/plugins/mcusupport/mcutargetfactory.h index 1a3588883aa..06752440435 100644 --- a/src/plugins/mcusupport/mcutargetfactory.h +++ b/src/plugins/mcusupport/mcutargetfactory.h @@ -33,6 +33,8 @@ namespace McuSupport::Internal { struct PackageDescription; +class McuPackageVersionDetector; + class McuTargetFactory : public McuAbstractTargetFactory { public: diff --git a/src/plugins/mcusupport/mcutargetfactorylegacy.cpp b/src/plugins/mcusupport/mcutargetfactorylegacy.cpp index 3bfa4a66e21..17cdb042f37 100644 --- a/src/plugins/mcusupport/mcutargetfactorylegacy.cpp +++ b/src/plugins/mcusupport/mcutargetfactorylegacy.cpp @@ -27,7 +27,6 @@ #include "mcuhelpers.h" #include "mcupackage.h" #include "mcusupportsdk.h" -#include "mcusupportversiondetection.h" #include "mcutarget.h" #include "mcutargetdescription.h" diff --git a/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h b/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h index 8f2de3c6a7b..82398214731 100644 --- a/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h +++ b/src/plugins/mcusupport/test/armgcc_nxp_1050_json.h @@ -65,16 +65,19 @@ constexpr auto armgcc_nxp_1050_json = R"({ "10.3.1" ], "compiler": { - "id": "ARMGCC_DIR", "label": "GNU Arm Embedded Toolchain", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "envVar": "ARMGCC_DIR", "setting": "GNUArmEmbeddedToolchain", "type": "path", - "optional": false + "optional": false, + "versionDetection" : { + "filePattern": "bin/arm-none-eabi-g++", + "executableArgs": "--version", + "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + } }, "file": { - "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", "label": "CMake Toolchain File", "cmakeVar": "CMAKE_TOOLCHAIN_FILE", "type": "file", @@ -84,13 +87,18 @@ constexpr auto armgcc_nxp_1050_json = R"({ } }, "boardSdk": { - "envVar": "EVKB_IMXRT1050_SDK_PATH", "versions": [ "2.11.0" ], "id": "NXP_SDK_DIR", "label": "Board SDK for MIMXRT1050-EVK", "cmakeVar": "QUL_BOARD_SDK_DIR", "envVar": "EVKB_IMXRT1050_SDK_PATH", "setting": "EVKB_IMXRT1050_SDK_PATH", + "versionDetection" : { + "filePattern": "*_manifest_*.xml", + "xmlElement": "ksdk", + "xmlAttribute": "version", + "regex": ".*" + }, "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 b5a58c53be3..ec4b1de0812 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_freertos_json.h @@ -71,7 +71,12 @@ constexpr auto armgcc_stm32f769i_freertos_json = R"({ "envVar": "ARMGCC_DIR", "setting": "GNUArmEmbeddedToolchain", "type": "path", - "optional": false + "optional": false, + "versionDetection" : { + "filePattern": "bin/arm-none-eabi-g++", + "executableArgs": "--version", + "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + } }, "file": { "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", @@ -86,10 +91,13 @@ constexpr auto armgcc_stm32f769i_freertos_json = R"({ "boardSdk": { "envVar": "STM32Cube_FW_F7_SDK_PATH", "setting": "STM32Cube_FW_F7_SDK_PATH", - "versions": [ - "1.16.0" - ], - "id": "ST_SDK_DIR", + "versions": [ "1.16.0" ], + "versionDetection" : { + "filePattern": "package.xml", + "xmlElement": "PackDescription", + "xmlAttribute": "Release", + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" + }, "label": "Board SDK for STM32F769I-Discovery", "cmakeVar": "QUL_BOARD_SDK_DIR", "type": "path", diff --git a/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h b/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h index b54ce148ea6..af67137b1b3 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32h750b_metal_json.h @@ -26,7 +26,7 @@ #pragma once constexpr auto armgcc_stm32h750b_metal_json = R"({ - "qulVersion": "2.0.0", + "qulVersion": "2.3.0", "compatVersion": "1", "platform": { "id": "STM32H750B-DISCOVERY-BAREMETAL", @@ -69,7 +69,12 @@ constexpr auto armgcc_stm32h750b_metal_json = R"({ "envVar": "ARMGCC_DIR", "setting": "GNUArmEmbeddedToolchain", "type": "path", - "optional": false + "optional": false, + "versionDetection" : { + "filePattern": "bin/arm-none-eabi-g++", + "executableArgs": "--version", + "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + } }, "file" : { "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", @@ -87,6 +92,12 @@ constexpr auto armgcc_stm32h750b_metal_json = R"({ "versions": [ "1.5.0" ], + "versionDetection" : { + "filePattern": "package.xml", + "xmlElement": "PackDescription", + "xmlAttribute": "Release", + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" + }, "id": "ST_SDK_DIR", "label": "Board SDK for STM32H750B-Discovery", "cmakeVar": "QUL_BOARD_SDK_DIR", diff --git a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h index 5dc2f0ce255..d767125e7e7 100644 --- a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h @@ -77,6 +77,11 @@ constexpr auto ghs_rh850_d1m1a_baremetal_json = R"({ "cmakeVar": "QUL_BOARD_SDK_DIR", "type": "path", "defaultValue": "/Renesas_Electronics/D1x_RGL/rgl_ghs_D1Mx_obj_V.2.0.0a", + "versionDetection": { + "filePattern" : "rgl_*_obj_*", + "regex" : "\\d+\\.\\d+\\.\\w+", + "isFile" : false + }, "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 3a7f9240408..be904baf203 100644 --- a/src/plugins/mcusupport/test/iar_nxp_1064_json.h +++ b/src/plugins/mcusupport/test/iar_nxp_1064_json.h @@ -35,6 +35,12 @@ constexpr auto iar_nxp_1064_json = R"({ "optional": false, "type": "path", "versions": ["2.11.0"], + "versionDetection" : { + "filePattern": "*_manifest_*.xml", + "xmlElement": "ksdk", + "xmlAttribute": "version", + "regex": ".*" + }, "envVar": "EVK_MIMXRT1064_SDK_PATH", "setting": "EVK_MIMXRT1064_SDK_PATH" }, diff --git a/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h b/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h index 8b462ef04b7..f5d63ecf130 100644 --- a/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f469i_metal_json.h @@ -69,7 +69,11 @@ constexpr auto iar_stm32f469i_metal_json = R"({ "label": "IAR ARM Compiler", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", - "optional": false + "versionDetection" : { + "filePattern": "bin/iccarm", + "executableArgs": "--version", + "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" + } }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", @@ -85,6 +89,12 @@ constexpr auto iar_stm32f469i_metal_json = R"({ "envVar": "STM32Cube_FW_F4_SDK_PATH", "setting": "STM32Cube_FW_F4_SDK_PATH", "versions": [ "1.25.0" ], + "versionDetection" : { + "filePattern": "package.xml", + "xmlElement": "PackDescription", + "xmlAttribute": "Release", + "regex": "\b(\d+\.\d+\.\d+)\b" + }, "id": "ST_SDK_DIR", "label": "Board SDK for STM32F469I-Discovery", "cmakeVar": "QUL_BOARD_SDK_DIR", diff --git a/src/plugins/mcusupport/test/packagemock.h b/src/plugins/mcusupport/test/packagemock.h index 5268fb81d63..0a3744d0697 100644 --- a/src/plugins/mcusupport/test/packagemock.h +++ b/src/plugins/mcusupport/test/packagemock.h @@ -53,5 +53,6 @@ public: MOCK_METHOD(QStringList, versions, (), (const)); MOCK_METHOD(QWidget *, widget, ()); + MOCK_METHOD(const McuPackageVersionDetector *, getVersionDetector, (), (const)); }; // class PackageMock } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 6998cb67606..7243c84f7fa 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -65,17 +65,20 @@ #include #include +#include namespace McuSupport::Internal::Test { namespace { const char empty[]{""}; +const char armGcc[]{"armgcc"}; +const char armGccVersionDetectionRegex[]{R"(\bv(\d+\.\d+\.\d+)\b)"}; const char armGccDir[]{"/opt/armgcc"}; const char armGccDirectorySetting[]{"GNUArmEmbeddedToolchain"}; const char armGccEnvVar[]{"ARMGCC_DIR"}; const char armGccLabel[]{"GNU Arm Embedded Toolchain"}; +const char armGccSuffix[]{"bin/arm-none-eabi-g++"}; const char armGccToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/armgcc.cmake"}; -const char armGcc[]{"armgcc"}; const char armGccVersion[]{"9.3.1"}; const char armGccNewVersion[]{"10.3.1"}; const QStringList boardSdkVersions{{"2.11.0"}}; @@ -96,6 +99,7 @@ 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 iarVersionDetectionRegex[]{R"(\bV(\d+\.\d+\.\d+)\.\d+\b)"}; const QStringList iarVersions{{"8.50.9"}}; const char iar[]{"iar"}; const char id[]{"target_id"}; @@ -141,7 +145,6 @@ using ProjectExplorer::EnvironmentKitAspect; using ProjectExplorer::Kit; using ProjectExplorer::KitManager; using ProjectExplorer::ToolChain; -using ProjectExplorer::ToolChainFactory; using ProjectExplorer::ToolChainManager; using testing::_; @@ -149,8 +152,9 @@ using testing::Return; void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) { + ProjectExplorer::ToolChainFactory toolchainFactory; Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; - ToolChain *iarToolchain{ToolChainFactory::createToolChain(iarId)}; + ToolChain *iarToolchain{toolchainFactory.createToolChain(iarId)}; iarToolchain->setLanguage(cxxLanguageId); ToolChainManager::instance()->registerToolChain(iarToolchain); @@ -172,9 +176,10 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QStringList &versions) { //Fake register and fake detect compiler. + ProjectExplorer::ToolChainFactory toolchainFactory; Id armGccId{ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID}; - ToolChain *armToolchain{ProjectExplorer::ToolChainFactory::createToolChain(armGccId)}; + ToolChain *armToolchain{toolchainFactory.createToolChain(armGccId)}; armToolchain->setLanguage(cxxLanguageId); ToolChainManager::instance()->registerToolChain(armToolchain); @@ -241,8 +246,8 @@ void verifyBoardSdk(const McuPackagePtr &boardSdk, McuSupportTest::McuSupportTest() : targetFactory{settingsMockPtr} - , compilerDescription{armGccLabel, armGccEnvVar, Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, false} - , toochainFileDescription{armGccLabel, armGccEnvVar, Legacy::Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, false} + , compilerDescription{armGccLabel, armGccEnvVar, Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} + , toochainFileDescription{armGccLabel, armGccEnvVar, Legacy::Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} , targetDescription { "2.0.1", "2", @@ -258,8 +263,11 @@ McuSupportTest::McuSupportTest() {}, // detectionPath {}, // settingsKey McuToolChainPackage::ToolChainType::Unsupported, // toolchain type + {}, // versions {}, // cmake var name - {}}} // env var name + {}, // env var name + nullptr // version detector + }} , armGccToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr, armGccLabel, armGccDir, @@ -268,7 +276,8 @@ McuSupportTest::McuSupportTest() McuToolChainPackage::ToolChainType::ArmGcc, {armGccVersion}, Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, - armGccEnvVar}} + armGccEnvVar, + nullptr}} , iarToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr, iarLabel, iarDir, @@ -277,7 +286,8 @@ McuSupportTest::McuSupportTest() McuToolChainPackage::ToolChainType::IAR, {armGccVersion}, Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, - iarEnvVar}} + iarEnvVar, + nullptr}} , platform{id, name, vendor} , mcuTarget{currentQulVersion, platform, @@ -585,6 +595,7 @@ void McuSupportTest::test_createTargets() freeRtosPath, "", {}, + VersionDetection{}, true}; targetDescription.freeRTOS.packages.append(packageDescription); targetDescription.toolchain.id = armGcc; @@ -637,6 +648,7 @@ void McuSupportTest::test_createPackages() freeRtosPath, "", {}, + VersionDetection{}, true}; targetDescription.freeRTOS.packages.append(packageDescription); @@ -649,8 +661,8 @@ void McuSupportTest::test_removeRtosSuffixFromEnvironmentVariable_data() QTest::addColumn("freeRtosEnvVar"); QTest::addColumn("expectedEnvVarWithoutSuffix"); - QTest::newRow("nxp1050") << nxp1050FreeRtosEnvVar << nxp1050; - QTest::newRow("nxp1064") << nxp1064FreeRtosEnvVar << nxp1064; + QTest::newRow("armgcc_nxp_1050_json") << nxp1050FreeRtosEnvVar << nxp1050; + QTest::newRow("iar_nxp_1064_json") << nxp1064FreeRtosEnvVar << nxp1064; QTest::newRow("nxp1170") << nxp1170FreeRtosEnvVar << nxp1170; QTest::newRow("stm32f7") << stm32f7FreeRtosEnvVar << stm32f7; } @@ -682,6 +694,7 @@ void McuSupportTest::test_useFallbackPathForToolchainWhenPathFromSettingsIsNotAv fallbackDir, {}, {}, + VersionDetection{}, false}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; @@ -704,6 +717,7 @@ void McuSupportTest::test_usePathFromSettingsForToolchainPath() empty, {}, {}, + VersionDetection{}, false}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; @@ -796,10 +810,8 @@ void McuSupportTest::test_legacy_createTargetWithToolchainPackages_data() << QStringList{armGccVersion, armGccNewVersion}; QTest::newRow("stm32f469i") << iar_stm32f469i_metal_json << iarToolchainFilePath << iarDir << iarSetting << iarVersions; - QTest::newRow("nxp1064") << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting - << iarVersions; - QTest::newRow("nxp1064") << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting - << iarVersions; + QTest::newRow("iar_nxp_1064_json") + << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting << iarVersions; QTest::newRow("ghs_rh850_d1m1a_baremetal_json") << ghs_rh850_d1m1a_baremetal_json << greenhillToolchainFilePath << greenhillCompilerDir << greenhillSetting << greenhillVersions; @@ -932,4 +944,156 @@ void McuSupportTest::test_legacy_createQtMCUsPackage() QCOMPARE(qtForMCUsSDK->path().toString(), qtForMcuSdkPath); } +void McuSupportTest::test_legacy_supportMultipleToolchainVersions() +{ + const auto description = parseDescriptionJson(armgcc_stm32f769i_freertos_json); + + QVERIFY(!description.toolchain.versions.empty()); + QCOMPARE(description.toolchain.versions.size(), 2); +} + +void McuSupportTest::test_passExecutableVersionDetectorToToolchainPackage_data() +{ + const char version[]{"--version"}; + + QTest::addColumn("json"); + QTest::addColumn("versionDetectionPath"); + QTest::addColumn("versionDetectionArgs"); + QTest::addColumn("versionRegex"); + QTest::newRow("armgcc_nxp_1050_json") + << armgcc_nxp_1050_json << armGccSuffix << version << armGccVersionDetectionRegex; + QTest::newRow("armgcc_stm32h750b_metal_json") + << armgcc_stm32h750b_metal_json << armGccSuffix << version << armGccVersionDetectionRegex; + QTest::newRow("armgcc_stm32f769i_freertos_json") + << armgcc_stm32f769i_freertos_json << armGccSuffix << version + << armGccVersionDetectionRegex; + + QTest::newRow("iar_stm32f469i_metal_json") << iar_stm32f469i_metal_json << QString{"bin/iccarm"} + << version << iarVersionDetectionRegex; +} + +void McuSupportTest::test_passExecutableVersionDetectorToToolchainPackage() +{ + QFETCH(QString, json); + QFETCH(QString, versionDetectionPath); + QFETCH(QString, versionDetectionArgs); + QFETCH(QString, versionRegex); + const McuTargetDescription description = parseDescriptionJson(json.toLocal8Bit()); + + QCOMPARE(description.toolchain.compiler.versionDetection.filePattern, versionDetectionPath); + QCOMPARE(description.toolchain.compiler.versionDetection.executableArgs, versionDetectionArgs); + QCOMPARE(description.toolchain.compiler.versionDetection.regex, versionRegex); + + McuToolChainPackagePtr toolchain{targetFactory.createToolchain(description.toolchain)}; + + const auto *versionDetector{toolchain->getVersionDetector()}; + QVERIFY(versionDetector != nullptr); + + QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackageExecutableVersionDetector).name()); +} + +void McuSupportTest::test_legacy_passExecutableVersionDetectorToToolchainPackage_data() +{ + test_passExecutableVersionDetectorToToolchainPackage_data(); +} + +void McuSupportTest::test_legacy_passExecutableVersionDetectorToToolchainPackage() +{ + QFETCH(QString, json); + QFETCH(QString, versionDetectionPath); + QFETCH(QString, versionDetectionArgs); + QFETCH(QString, versionRegex); + + const McuTargetDescription description = parseDescriptionJson(json.toLocal8Bit()); + McuToolChainPackagePtr toolchain{targetFactory.createToolchain(description.toolchain)}; + + const auto *versionDetector{toolchain->getVersionDetector()}; + QVERIFY(versionDetector != nullptr); + + QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackageExecutableVersionDetector).name()); +} + +void McuSupportTest::test_legacy_passXMLVersionDetectorToNxpAndStmBoardSdkPackage_data() +{ + QTest::addColumn("json"); + QTest::addColumn("xmlElement"); + QTest::addColumn("xmlAttribute"); + QTest::addColumn("filePattern"); + + QTest::newRow("armgcc_nxp_1050_json") << armgcc_nxp_1050_json << "ksdk" + << "version" + << "*_manifest_*.xml"; + QTest::newRow("armgcc_stm32h750b_metal_json") + << armgcc_stm32h750b_metal_json << "PackDescription" + << "Release" + << "package.xml"; + QTest::newRow("armgcc_stm32f769i_freertos_json") + << armgcc_stm32f769i_freertos_json << "PackDescription" + << "Release" + << "package.xml"; + QTest::newRow("iar_stm32f469i_metal_json") << iar_stm32f469i_metal_json << "PackDescription" + << "Release" + << "package.xml"; + QTest::newRow("iar_nxp_1064_json") << iar_nxp_1064_json << "ksdk" + << "version" + << "*_manifest_*.xml"; +} + +void McuSupportTest::test_legacy_passXMLVersionDetectorToNxpAndStmBoardSdkPackage() +{ + QFETCH(QString, json); + QFETCH(QString, xmlElement); + QFETCH(QString, xmlAttribute); + QFETCH(QString, filePattern); + + const McuTargetDescription description = parseDescriptionJson(json.toLocal8Bit()); + McuPackagePtr boardSdk{Legacy::createBoardSdkPackage(settingsMockPtr, description)}; + + const auto *versionDetector{boardSdk->getVersionDetector()}; + QVERIFY(versionDetector != nullptr); + + QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackageXmlVersionDetector).name()); +} + +void McuSupportTest::test_passXMLVersionDetectorToNxpAndStmBoardSdkPackage_data() +{ + test_legacy_passXMLVersionDetectorToNxpAndStmBoardSdkPackage_data(); +} + +void McuSupportTest::test_passXMLVersionDetectorToNxpAndStmBoardSdkPackage() +{ + QFETCH(QString, json); + QFETCH(QString, xmlElement); + QFETCH(QString, xmlAttribute); + QFETCH(QString, filePattern); + + const McuTargetDescription description = parseDescriptionJson(json.toLocal8Bit()); + + QCOMPARE(description.boardSdk.versionDetection.xmlElement, xmlElement); + QCOMPARE(description.boardSdk.versionDetection.xmlAttribute, xmlAttribute); + QCOMPARE(description.boardSdk.versionDetection.filePattern, filePattern); + + McuPackagePtr boardSdk{targetFactory.createPackage(description.boardSdk)}; + + const auto *versionDetector{boardSdk->getVersionDetector()}; + QVERIFY(versionDetector != nullptr); + + QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackageXmlVersionDetector).name()); +} + +void McuSupportTest::test_passDirectoryVersionDetectorToRenesasBoardSdkPackage() +{ + const McuTargetDescription description = parseDescriptionJson(ghs_rh850_d1m1a_baremetal_json); + + QCOMPARE(description.boardSdk.versionDetection.filePattern, "rgl_*_obj_*"); + QCOMPARE(description.boardSdk.versionDetection.regex, R"(\d+\.\d+\.\w+)"); + QCOMPARE(description.boardSdk.versionDetection.isFile, false); + + McuPackagePtr boardSdk{targetFactory.createPackage(description.boardSdk)}; + + const auto *versionDetector{boardSdk->getVersionDetector()}; + QVERIFY(versionDetector != nullptr); + QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackageDirectoryVersionDetector).name()); +} + } // namespace McuSupport::Internal::Test diff --git a/src/plugins/mcusupport/test/unittest.h b/src/plugins/mcusupport/test/unittest.h index 6d9b21642ac..f95294ed58f 100644 --- a/src/plugins/mcusupport/test/unittest.h +++ b/src/plugins/mcusupport/test/unittest.h @@ -87,6 +87,17 @@ private slots: void test_getFullToolchainFilePathFromTarget(); void test_legacy_getPredefinedToolchainFilePackage(); void test_legacy_createUnsupportedToolchainFilePackage(); + void test_legacy_supportMultipleToolchainVersions(); + + void test_passExecutableVersionDetectorToToolchainPackage_data(); + void test_passExecutableVersionDetectorToToolchainPackage(); + void test_legacy_passExecutableVersionDetectorToToolchainPackage_data(); + void test_legacy_passExecutableVersionDetectorToToolchainPackage(); + void test_legacy_passXMLVersionDetectorToNxpAndStmBoardSdkPackage_data(); + void test_legacy_passXMLVersionDetectorToNxpAndStmBoardSdkPackage(); + void test_passXMLVersionDetectorToNxpAndStmBoardSdkPackage_data(); + void test_passXMLVersionDetectorToNxpAndStmBoardSdkPackage(); + void test_passDirectoryVersionDetectorToRenesasBoardSdkPackage(); void test_legacy_createBoardSdk_data(); void test_legacy_createBoardSdk();