McuSupport: Version detection handling for kit requirements

Create appropriate instance of version detector depending on
parsed data from JSON and pass it to McuPackage's ctor. Also tests.

Change-Id: I4f7e5cd6d998745dfe951284c34904526abc216b
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Piotr Mućko
2022-07-04 22:30:42 +02:00
parent 866f20e4f9
commit 5be5f7a331
19 changed files with 374 additions and 82 deletions

View File

@@ -33,6 +33,8 @@ class FilePath;
namespace McuSupport::Internal { namespace McuSupport::Internal {
class McuPackageVersionDetector;
class McuAbstractPackage : public QObject class McuAbstractPackage : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -67,6 +69,7 @@ public:
virtual bool writeToSettings() const = 0; virtual bool writeToSettings() const = 0;
virtual QWidget *widget() = 0; virtual QWidget *widget() = 0;
virtual const McuPackageVersionDetector *getVersionDetector() const = 0;
signals: signals:
void changed(); void changed();

View File

@@ -108,6 +108,11 @@ QStringList McuPackage::versions() const
return m_versions; return m_versions;
} }
const McuPackageVersionDetector *McuPackage::getVersionDetector() const
{
return m_versionDetector.get();
}
FilePath McuPackage::basePath() const FilePath McuPackage::basePath() const
{ {
return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path; return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path;

View File

@@ -48,8 +48,6 @@ class Id;
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
class McuPackageVersionDetector;
class McuPackage : public McuAbstractPackage class McuPackage : public McuAbstractPackage
{ {
Q_OBJECT Q_OBJECT
@@ -90,6 +88,7 @@ public:
bool writeToSettings() const override; bool writeToSettings() const override;
QWidget *widget() override; QWidget *widget() override;
const McuPackageVersionDetector *getVersionDetector() const override;
private: private:
void updatePath(); void updatePath();
@@ -116,9 +115,9 @@ private:
const bool m_addToSystemPath; const bool m_addToSystemPath;
Status m_status = Status::InvalidPath; Status m_status = Status::InvalidPath;
}; }; // class McuPackage
class McuToolChainPackage : public McuPackage class McuToolChainPackage final : public McuPackage
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -132,8 +131,8 @@ public:
ToolChainType toolchainType, ToolChainType toolchainType,
const QStringList &versions, const QStringList &versions,
const QString &cmakeVarName, const QString &cmakeVarName,
const QString &envVarName = {}, const QString &envVarName,
const McuPackageVersionDetector *versionDetector = nullptr); const McuPackageVersionDetector *versionDetector);
ToolChainType toolchainType() const; ToolChainType toolchainType() const;
bool isDesktopToolchain() const; bool isDesktopToolchain() const;

View File

@@ -107,9 +107,6 @@ static McuPackageVersionDetector *generatePackageVersionDetector(const QString &
return nullptr; 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, McuPackagePtr createBoardSdkPackage(const SettingsHandler::Ptr &settingsHandler,
const McuTargetDescription &desc) const McuTargetDescription &desc)
{ {
@@ -191,22 +188,47 @@ McuPackagePtr createUnsupportedToolChainFilePackage(const SettingsHandler::Ptr &
McuToolChainPackagePtr createUnsupportedToolChainPackage(const SettingsHandler::Ptr &settingsHandler) McuToolChainPackagePtr createUnsupportedToolChainPackage(const SettingsHandler::Ptr &settingsHandler)
{ {
return McuToolChainPackagePtr{new McuToolChainPackage( return McuToolChainPackagePtr{
settingsHandler, {}, {}, {}, {}, McuToolChainPackage::ToolChainType::Unsupported, {}, {})}; new McuToolChainPackage(settingsHandler,
{},
{},
{},
{},
McuToolChainPackage::ToolChainType::Unsupported,
{},
{},
{},
nullptr)};
} }
McuToolChainPackagePtr createMsvcToolChainPackage(const SettingsHandler::Ptr &settingsHandler, McuToolChainPackagePtr createMsvcToolChainPackage(const SettingsHandler::Ptr &settingsHandler,
const QStringList &versions) const QStringList &versions)
{ {
return McuToolChainPackagePtr{new McuToolChainPackage( return McuToolChainPackagePtr{new McuToolChainPackage(settingsHandler,
settingsHandler, {}, {}, {}, {}, McuToolChainPackage::ToolChainType::MSVC, versions, {})}; {},
{},
{},
{},
McuToolChainPackage::ToolChainType::MSVC,
versions,
{},
{},
nullptr)};
} }
McuToolChainPackagePtr createGccToolChainPackage(const SettingsHandler::Ptr &settingsHandler, McuToolChainPackagePtr createGccToolChainPackage(const SettingsHandler::Ptr &settingsHandler,
const QStringList &versions) const QStringList &versions)
{ {
return McuToolChainPackagePtr{new McuToolChainPackage( return McuToolChainPackagePtr{new McuToolChainPackage(settingsHandler,
settingsHandler, {}, {}, {}, {}, McuToolChainPackage::ToolChainType::GCC, versions, {})}; {},
{},
{},
{},
McuToolChainPackage::ToolChainType::GCC,
versions,
{},
{},
nullptr)};
} }
McuToolChainPackagePtr createArmGccToolchainPackage(const SettingsHandler::Ptr &settingsHandler, 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 Utils::FilePath detectionPath = FilePath("bin/arm-none-eabi-g++").withExecutableSuffix();
const auto versionDetector const auto versionDetector = new McuPackageExecutableVersionDetector(detectionPath,
= new McuPackageExecutableVersionDetector(detectionPath, {"--version"},
{"--version"}, R"(\b(\d+\.\d+\.\d+)\b)");
"\\b(\\d+\\.\\d+\\.\\d+)\\b");
return McuToolChainPackagePtr{ return McuToolChainPackagePtr{
new McuToolChainPackage(settingsHandler, new McuToolChainPackage(settingsHandler,
@@ -257,7 +278,7 @@ McuToolChainPackagePtr createGhsToolchainPackage(const SettingsHandler::Ptr &set
const auto versionDetector const auto versionDetector
= new McuPackageExecutableVersionDetector(FilePath("as850").withExecutableSuffix(), = new McuPackageExecutableVersionDetector(FilePath("as850").withExecutableSuffix(),
{"-V"}, {"-V"},
"\\bv(\\d+\\.\\d+\\.\\d+)\\b"); R"(\bv(\d+\.\d+\.\d+)\b)");
return McuToolChainPackagePtr{ return McuToolChainPackagePtr{
new McuToolChainPackage(settingsHandler, new McuToolChainPackage(settingsHandler,
@@ -282,7 +303,7 @@ McuToolChainPackagePtr createGhsArmToolchainPackage(const SettingsHandler::Ptr &
const auto versionDetector const auto versionDetector
= new McuPackageExecutableVersionDetector(FilePath("asarm").withExecutableSuffix(), = new McuPackageExecutableVersionDetector(FilePath("asarm").withExecutableSuffix(),
{"-V"}, {"-V"},
"\\bv(\\d+\\.\\d+\\.\\d+)\\b"); R"(\bv(\d+\.\d+\.\d+)\b)");
return McuToolChainPackagePtr{ return McuToolChainPackagePtr{
new McuToolChainPackage(settingsHandler, new McuToolChainPackage(settingsHandler,
@@ -317,10 +338,10 @@ McuToolChainPackagePtr createIarToolChainPackage(const SettingsHandler::Ptr &set
} }
const FilePath detectionPath = FilePath("bin/iccarm").withExecutableSuffix(); const FilePath detectionPath = FilePath("bin/iccarm").withExecutableSuffix();
const auto versionDetector const auto *versionDetector
= new McuPackageExecutableVersionDetector(detectionPath, = new McuPackageExecutableVersionDetector(detectionPath,
{"--version"}, {"--version"},
"\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b"); R"(\bV(\d+\.\d+\.\d+)\.\d+\b)");
return McuToolChainPackagePtr{ return McuToolChainPackagePtr{
new McuToolChainPackage(settingsHandler, new McuToolChainPackage(settingsHandler,
@@ -585,6 +606,19 @@ static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir)
return kitsDir.entryInfoList(); 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) static PackageDescription parsePackage(const QJsonObject &cmakeEntry)
{ {
const QVariantList versionsVariantList = cmakeEntry["versions"].toArray().toVariantList(); 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["defaultValue"].toString()),
FilePath::fromString(cmakeEntry["validation"].toString()), FilePath::fromString(cmakeEntry["validation"].toString()),
versions, versions,
parseVersionDetection(cmakeEntry),
false}; false};
} }
@@ -688,7 +723,7 @@ static const QString legacySupportVersionFor(const QString &sdkVersion)
bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message) 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 sdkDetectedVersion = versionDetector.parseVersion(qulDir);
const QString legacyVersion = legacySupportVersionFor(sdkDetectedVersion); const QString legacyVersion = legacySupportVersionFor(sdkDetectedVersion);

View File

@@ -45,12 +45,8 @@ QString matchRegExp(const QString &text, const QString &regExp)
return QString(); return QString();
} }
McuPackageVersionDetector::McuPackageVersionDetector() {}
McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector( McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector(
const FilePath &detectionPath, const FilePath &detectionPath, const QStringList &detectionArgs, const QString &detectionRegExp)
const QStringList &detectionArgs,
const QString &detectionRegExp)
: McuPackageVersionDetector() : McuPackageVersionDetector()
, m_detectionPath(detectionPath) , m_detectionPath(detectionPath)
, m_detectionArgs(detectionArgs) , m_detectionArgs(detectionArgs)
@@ -133,7 +129,7 @@ McuPackagePathVersionDetector::McuPackagePathVersionDetector(const QString &vers
QString McuPackagePathVersionDetector::parseVersion(const FilePath &packagePath) const QString McuPackagePathVersionDetector::parseVersion(const FilePath &packagePath) const
{ {
if (!packagePath.exists()) if (!packagePath.exists())
return QString(); return {};
return matchRegExp(packagePath.toString(), m_versionRegExp); return matchRegExp(packagePath.toString(), m_versionRegExp);
} }

View File

@@ -33,7 +33,7 @@ namespace McuSupport::Internal {
class McuPackageVersionDetector class McuPackageVersionDetector
{ {
public: public:
McuPackageVersionDetector(); McuPackageVersionDetector() = default;
virtual ~McuPackageVersionDetector() = default; virtual ~McuPackageVersionDetector() = default;
virtual QString parseVersion(const Utils::FilePath &packagePath) const = 0; virtual QString parseVersion(const Utils::FilePath &packagePath) const = 0;
}; };

View File

@@ -33,6 +33,16 @@
namespace McuSupport::Internal { namespace McuSupport::Internal {
struct VersionDetection
{
QString regex;
QString filePattern;
QString executableArgs;
QString xmlElement;
QString xmlAttribute;
bool isFile;
}; // struct VersionDetection
struct PackageDescription struct PackageDescription
{ {
QString label; QString label;
@@ -43,6 +53,7 @@ struct PackageDescription
Utils::FilePath defaultPath; Utils::FilePath defaultPath;
Utils::FilePath validationPath; Utils::FilePath validationPath;
QStringList versions; QStringList versions;
VersionDetection versionDetection;
bool shouldAddToSystemPath; bool shouldAddToSystemPath;
}; //struct PackageDescription }; //struct PackageDescription

View File

@@ -59,6 +59,24 @@ const static QMap<QString, McuToolChainPackage::ToolChainType> toolchainTypeMapp
{"ghsarm", McuToolChainPackage::ToolChainType::GHSArm}, {"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) McuTargetFactory::McuTargetFactory(const SettingsHandler::Ptr &settingsHandler)
: settingsHandler{settingsHandler} : settingsHandler{settingsHandler}
{} {}
@@ -116,16 +134,16 @@ Packages McuTargetFactory::createPackages(const McuTargetDescription &desc)
McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc) McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc)
{ {
return McuPackagePtr{new McuPackage{ return McuPackagePtr{new McuPackage{settingsHandler,
settingsHandler, pkgDesc.label,
pkgDesc.label, pkgDesc.defaultPath,
pkgDesc.defaultPath, pkgDesc.validationPath,
pkgDesc.validationPath, pkgDesc.setting,
pkgDesc.setting, pkgDesc.cmakeVar,
pkgDesc.cmakeVar, pkgDesc.envVar,
pkgDesc.envVar, pkgDesc.versions,
pkgDesc.versions, {},
}}; createVersionDetection(pkgDesc.versionDetection)}};
} }
McuToolChainPackage *McuTargetFactory::createToolchain( McuToolChainPackage *McuTargetFactory::createToolchain(
@@ -144,22 +162,22 @@ McuToolChainPackage *McuTargetFactory::createToolchain(
{}, {},
toolchainType, toolchainType,
toolchain.versions, toolchain.versions,
compilerDescription.cmakeVar}; compilerDescription.cmakeVar,
{},
nullptr};
else if (!isToolchainDescriptionValid(toolchain)) else if (!isToolchainDescriptionValid(toolchain))
toolchainType = McuToolChainPackage::ToolChainType::Unsupported; toolchainType = McuToolChainPackage::ToolChainType::Unsupported;
return new McuToolChainPackage{ return new McuToolChainPackage{settingsHandler,
settingsHandler, compilerDescription.label,
compilerDescription.label, compilerDescription.defaultPath,
compilerDescription.defaultPath, compilerDescription.validationPath,
compilerDescription.validationPath, compilerDescription.setting,
compilerDescription.setting, toolchainType,
toolchainType, toolchain.versions,
toolchain.versions, compilerDescription.cmakeVar,
compilerDescription.cmakeVar, compilerDescription.envVar,
compilerDescription.envVar, createVersionDetection(compilerDescription.versionDetection)};
nullptr, // McuPackageVersionDetector
};
} }
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -33,6 +33,8 @@ namespace McuSupport::Internal {
struct PackageDescription; struct PackageDescription;
class McuPackageVersionDetector;
class McuTargetFactory : public McuAbstractTargetFactory class McuTargetFactory : public McuAbstractTargetFactory
{ {
public: public:

View File

@@ -27,7 +27,6 @@
#include "mcuhelpers.h" #include "mcuhelpers.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcusupportversiondetection.h"
#include "mcutarget.h" #include "mcutarget.h"
#include "mcutargetdescription.h" #include "mcutargetdescription.h"

View File

@@ -65,16 +65,19 @@ constexpr auto armgcc_nxp_1050_json = R"({
"10.3.1" "10.3.1"
], ],
"compiler": { "compiler": {
"id": "ARMGCC_DIR",
"label": "GNU Arm Embedded Toolchain", "label": "GNU Arm Embedded Toolchain",
"cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR",
"envVar": "ARMGCC_DIR", "envVar": "ARMGCC_DIR",
"setting": "GNUArmEmbeddedToolchain", "setting": "GNUArmEmbeddedToolchain",
"type": "path", "type": "path",
"optional": false "optional": false,
"versionDetection" : {
"filePattern": "bin/arm-none-eabi-g++",
"executableArgs": "--version",
"regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b"
}
}, },
"file": { "file": {
"id": "ARMGCC_CMAKE_TOOLCHAIN_FILE",
"label": "CMake Toolchain File", "label": "CMake Toolchain File",
"cmakeVar": "CMAKE_TOOLCHAIN_FILE", "cmakeVar": "CMAKE_TOOLCHAIN_FILE",
"type": "file", "type": "file",
@@ -84,13 +87,18 @@ constexpr auto armgcc_nxp_1050_json = R"({
} }
}, },
"boardSdk": { "boardSdk": {
"envVar": "EVKB_IMXRT1050_SDK_PATH",
"versions": [ "2.11.0" ], "versions": [ "2.11.0" ],
"id": "NXP_SDK_DIR", "id": "NXP_SDK_DIR",
"label": "Board SDK for MIMXRT1050-EVK", "label": "Board SDK for MIMXRT1050-EVK",
"cmakeVar": "QUL_BOARD_SDK_DIR", "cmakeVar": "QUL_BOARD_SDK_DIR",
"envVar": "EVKB_IMXRT1050_SDK_PATH", "envVar": "EVKB_IMXRT1050_SDK_PATH",
"setting": "EVKB_IMXRT1050_SDK_PATH", "setting": "EVKB_IMXRT1050_SDK_PATH",
"versionDetection" : {
"filePattern": "*_manifest_*.xml",
"xmlElement": "ksdk",
"xmlAttribute": "version",
"regex": ".*"
},
"type": "path", "type": "path",
"optional": false "optional": false
}, },

View File

@@ -71,7 +71,12 @@ constexpr auto armgcc_stm32f769i_freertos_json = R"({
"envVar": "ARMGCC_DIR", "envVar": "ARMGCC_DIR",
"setting": "GNUArmEmbeddedToolchain", "setting": "GNUArmEmbeddedToolchain",
"type": "path", "type": "path",
"optional": false "optional": false,
"versionDetection" : {
"filePattern": "bin/arm-none-eabi-g++",
"executableArgs": "--version",
"regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b"
}
}, },
"file": { "file": {
"id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE",
@@ -86,10 +91,13 @@ constexpr auto armgcc_stm32f769i_freertos_json = R"({
"boardSdk": { "boardSdk": {
"envVar": "STM32Cube_FW_F7_SDK_PATH", "envVar": "STM32Cube_FW_F7_SDK_PATH",
"setting": "STM32Cube_FW_F7_SDK_PATH", "setting": "STM32Cube_FW_F7_SDK_PATH",
"versions": [ "versions": [ "1.16.0" ],
"1.16.0" "versionDetection" : {
], "filePattern": "package.xml",
"id": "ST_SDK_DIR", "xmlElement": "PackDescription",
"xmlAttribute": "Release",
"regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b"
},
"label": "Board SDK for STM32F769I-Discovery", "label": "Board SDK for STM32F769I-Discovery",
"cmakeVar": "QUL_BOARD_SDK_DIR", "cmakeVar": "QUL_BOARD_SDK_DIR",
"type": "path", "type": "path",

View File

@@ -26,7 +26,7 @@
#pragma once #pragma once
constexpr auto armgcc_stm32h750b_metal_json = R"({ constexpr auto armgcc_stm32h750b_metal_json = R"({
"qulVersion": "2.0.0", "qulVersion": "2.3.0",
"compatVersion": "1", "compatVersion": "1",
"platform": { "platform": {
"id": "STM32H750B-DISCOVERY-BAREMETAL", "id": "STM32H750B-DISCOVERY-BAREMETAL",
@@ -69,7 +69,12 @@ constexpr auto armgcc_stm32h750b_metal_json = R"({
"envVar": "ARMGCC_DIR", "envVar": "ARMGCC_DIR",
"setting": "GNUArmEmbeddedToolchain", "setting": "GNUArmEmbeddedToolchain",
"type": "path", "type": "path",
"optional": false "optional": false,
"versionDetection" : {
"filePattern": "bin/arm-none-eabi-g++",
"executableArgs": "--version",
"regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b"
}
}, },
"file" : { "file" : {
"id": "ARMGCC_CMAKE_TOOLCHAIN_FILE", "id": "ARMGCC_CMAKE_TOOLCHAIN_FILE",
@@ -87,6 +92,12 @@ constexpr auto armgcc_stm32h750b_metal_json = R"({
"versions": [ "versions": [
"1.5.0" "1.5.0"
], ],
"versionDetection" : {
"filePattern": "package.xml",
"xmlElement": "PackDescription",
"xmlAttribute": "Release",
"regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b"
},
"id": "ST_SDK_DIR", "id": "ST_SDK_DIR",
"label": "Board SDK for STM32H750B-Discovery", "label": "Board SDK for STM32H750B-Discovery",
"cmakeVar": "QUL_BOARD_SDK_DIR", "cmakeVar": "QUL_BOARD_SDK_DIR",

View File

@@ -77,6 +77,11 @@ constexpr auto ghs_rh850_d1m1a_baremetal_json = R"({
"cmakeVar": "QUL_BOARD_SDK_DIR", "cmakeVar": "QUL_BOARD_SDK_DIR",
"type": "path", "type": "path",
"defaultValue": "/Renesas_Electronics/D1x_RGL/rgl_ghs_D1Mx_obj_V.2.0.0a", "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 "optional": false
} }
})"; })";

View File

@@ -35,6 +35,12 @@ constexpr auto iar_nxp_1064_json = R"({
"optional": false, "optional": false,
"type": "path", "type": "path",
"versions": ["2.11.0"], "versions": ["2.11.0"],
"versionDetection" : {
"filePattern": "*_manifest_*.xml",
"xmlElement": "ksdk",
"xmlAttribute": "version",
"regex": ".*"
},
"envVar": "EVK_MIMXRT1064_SDK_PATH", "envVar": "EVK_MIMXRT1064_SDK_PATH",
"setting": "EVK_MIMXRT1064_SDK_PATH" "setting": "EVK_MIMXRT1064_SDK_PATH"
}, },

View File

@@ -69,7 +69,11 @@ constexpr auto iar_stm32f469i_metal_json = R"({
"label": "IAR ARM Compiler", "label": "IAR ARM Compiler",
"cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR",
"type": "path", "type": "path",
"optional": false "versionDetection" : {
"filePattern": "bin/iccarm",
"executableArgs": "--version",
"regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b"
}
}, },
"file": { "file": {
"id": "IAR_CMAKE_TOOLCHAIN_FILE", "id": "IAR_CMAKE_TOOLCHAIN_FILE",
@@ -85,6 +89,12 @@ constexpr auto iar_stm32f469i_metal_json = R"({
"envVar": "STM32Cube_FW_F4_SDK_PATH", "envVar": "STM32Cube_FW_F4_SDK_PATH",
"setting": "STM32Cube_FW_F4_SDK_PATH", "setting": "STM32Cube_FW_F4_SDK_PATH",
"versions": [ "1.25.0" ], "versions": [ "1.25.0" ],
"versionDetection" : {
"filePattern": "package.xml",
"xmlElement": "PackDescription",
"xmlAttribute": "Release",
"regex": "\b(\d+\.\d+\.\d+)\b"
},
"id": "ST_SDK_DIR", "id": "ST_SDK_DIR",
"label": "Board SDK for STM32F469I-Discovery", "label": "Board SDK for STM32F469I-Discovery",
"cmakeVar": "QUL_BOARD_SDK_DIR", "cmakeVar": "QUL_BOARD_SDK_DIR",

View File

@@ -53,5 +53,6 @@ public:
MOCK_METHOD(QStringList, versions, (), (const)); MOCK_METHOD(QStringList, versions, (), (const));
MOCK_METHOD(QWidget *, widget, ()); MOCK_METHOD(QWidget *, widget, ());
MOCK_METHOD(const McuPackageVersionDetector *, getVersionDetector, (), (const));
}; // class PackageMock }; // class PackageMock
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -65,17 +65,20 @@
#include <QtTest> #include <QtTest>
#include <algorithm> #include <algorithm>
#include <type_traits>
namespace McuSupport::Internal::Test { namespace McuSupport::Internal::Test {
namespace { namespace {
const char empty[]{""}; const char empty[]{""};
const char armGcc[]{"armgcc"};
const char armGccVersionDetectionRegex[]{R"(\bv(\d+\.\d+\.\d+)\b)"};
const char armGccDir[]{"/opt/armgcc"}; const char armGccDir[]{"/opt/armgcc"};
const char armGccDirectorySetting[]{"GNUArmEmbeddedToolchain"}; const char armGccDirectorySetting[]{"GNUArmEmbeddedToolchain"};
const char armGccEnvVar[]{"ARMGCC_DIR"}; const char armGccEnvVar[]{"ARMGCC_DIR"};
const char armGccLabel[]{"GNU Arm Embedded Toolchain"}; 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 armGccToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/armgcc.cmake"};
const char armGcc[]{"armgcc"};
const char armGccVersion[]{"9.3.1"}; const char armGccVersion[]{"9.3.1"};
const char armGccNewVersion[]{"10.3.1"}; const char armGccNewVersion[]{"10.3.1"};
const QStringList boardSdkVersions{{"2.11.0"}}; 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 iarLabel[]{"IAR ARM Compiler"};
const char iarSetting[]{"IARToolchain"}; const char iarSetting[]{"IARToolchain"};
const char iarToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/iar.cmake"}; 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 QStringList iarVersions{{"8.50.9"}};
const char iar[]{"iar"}; const char iar[]{"iar"};
const char id[]{"target_id"}; const char id[]{"target_id"};
@@ -141,7 +145,6 @@ using ProjectExplorer::EnvironmentKitAspect;
using ProjectExplorer::Kit; using ProjectExplorer::Kit;
using ProjectExplorer::KitManager; using ProjectExplorer::KitManager;
using ProjectExplorer::ToolChain; using ProjectExplorer::ToolChain;
using ProjectExplorer::ToolChainFactory;
using ProjectExplorer::ToolChainManager; using ProjectExplorer::ToolChainManager;
using testing::_; using testing::_;
@@ -149,8 +152,9 @@ using testing::Return;
void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage)
{ {
ProjectExplorer::ToolChainFactory toolchainFactory;
Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID};
ToolChain *iarToolchain{ToolChainFactory::createToolChain(iarId)}; ToolChain *iarToolchain{toolchainFactory.createToolChain(iarId)};
iarToolchain->setLanguage(cxxLanguageId); iarToolchain->setLanguage(cxxLanguageId);
ToolChainManager::instance()->registerToolChain(iarToolchain); ToolChainManager::instance()->registerToolChain(iarToolchain);
@@ -172,9 +176,10 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage)
void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QStringList &versions) void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QStringList &versions)
{ {
//Fake register and fake detect compiler. //Fake register and fake detect compiler.
ProjectExplorer::ToolChainFactory toolchainFactory;
Id armGccId{ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID}; Id armGccId{ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID};
ToolChain *armToolchain{ProjectExplorer::ToolChainFactory::createToolChain(armGccId)}; ToolChain *armToolchain{toolchainFactory.createToolChain(armGccId)};
armToolchain->setLanguage(cxxLanguageId); armToolchain->setLanguage(cxxLanguageId);
ToolChainManager::instance()->registerToolChain(armToolchain); ToolChainManager::instance()->registerToolChain(armToolchain);
@@ -241,8 +246,8 @@ void verifyBoardSdk(const McuPackagePtr &boardSdk,
McuSupportTest::McuSupportTest() McuSupportTest::McuSupportTest()
: targetFactory{settingsMockPtr} : targetFactory{settingsMockPtr}
, compilerDescription{armGccLabel, armGccEnvVar, Legacy::Constants::TOOLCHAIN_DIR_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} , toochainFileDescription{armGccLabel, armGccEnvVar, Legacy::Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false}
, targetDescription { , targetDescription {
"2.0.1", "2.0.1",
"2", "2",
@@ -258,8 +263,11 @@ McuSupportTest::McuSupportTest()
{}, // detectionPath {}, // detectionPath
{}, // settingsKey {}, // settingsKey
McuToolChainPackage::ToolChainType::Unsupported, // toolchain type McuToolChainPackage::ToolChainType::Unsupported, // toolchain type
{}, // versions
{}, // cmake var name {}, // cmake var name
{}}} // env var name {}, // env var name
nullptr // version detector
}}
, armGccToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr, , armGccToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr,
armGccLabel, armGccLabel,
armGccDir, armGccDir,
@@ -268,7 +276,8 @@ McuSupportTest::McuSupportTest()
McuToolChainPackage::ToolChainType::ArmGcc, McuToolChainPackage::ToolChainType::ArmGcc,
{armGccVersion}, {armGccVersion},
Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE,
armGccEnvVar}} armGccEnvVar,
nullptr}}
, iarToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr, , iarToolchainPackagePtr{new McuToolChainPackage{settingsMockPtr,
iarLabel, iarLabel,
iarDir, iarDir,
@@ -277,7 +286,8 @@ McuSupportTest::McuSupportTest()
McuToolChainPackage::ToolChainType::IAR, McuToolChainPackage::ToolChainType::IAR,
{armGccVersion}, {armGccVersion},
Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE, Legacy::Constants::TOOLCHAIN_DIR_CMAKE_VARIABLE,
iarEnvVar}} iarEnvVar,
nullptr}}
, platform{id, name, vendor} , platform{id, name, vendor}
, mcuTarget{currentQulVersion, , mcuTarget{currentQulVersion,
platform, platform,
@@ -585,6 +595,7 @@ void McuSupportTest::test_createTargets()
freeRtosPath, freeRtosPath,
"", "",
{}, {},
VersionDetection{},
true}; true};
targetDescription.freeRTOS.packages.append(packageDescription); targetDescription.freeRTOS.packages.append(packageDescription);
targetDescription.toolchain.id = armGcc; targetDescription.toolchain.id = armGcc;
@@ -637,6 +648,7 @@ void McuSupportTest::test_createPackages()
freeRtosPath, freeRtosPath,
"", "",
{}, {},
VersionDetection{},
true}; true};
targetDescription.freeRTOS.packages.append(packageDescription); targetDescription.freeRTOS.packages.append(packageDescription);
@@ -649,8 +661,8 @@ void McuSupportTest::test_removeRtosSuffixFromEnvironmentVariable_data()
QTest::addColumn<QString>("freeRtosEnvVar"); QTest::addColumn<QString>("freeRtosEnvVar");
QTest::addColumn<QString>("expectedEnvVarWithoutSuffix"); QTest::addColumn<QString>("expectedEnvVarWithoutSuffix");
QTest::newRow("nxp1050") << nxp1050FreeRtosEnvVar << nxp1050; QTest::newRow("armgcc_nxp_1050_json") << nxp1050FreeRtosEnvVar << nxp1050;
QTest::newRow("nxp1064") << nxp1064FreeRtosEnvVar << nxp1064; QTest::newRow("iar_nxp_1064_json") << nxp1064FreeRtosEnvVar << nxp1064;
QTest::newRow("nxp1170") << nxp1170FreeRtosEnvVar << nxp1170; QTest::newRow("nxp1170") << nxp1170FreeRtosEnvVar << nxp1170;
QTest::newRow("stm32f7") << stm32f7FreeRtosEnvVar << stm32f7; QTest::newRow("stm32f7") << stm32f7FreeRtosEnvVar << stm32f7;
} }
@@ -682,6 +694,7 @@ void McuSupportTest::test_useFallbackPathForToolchainWhenPathFromSettingsIsNotAv
fallbackDir, fallbackDir,
{}, {},
{}, {},
VersionDetection{},
false}; false};
McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}};
@@ -704,6 +717,7 @@ void McuSupportTest::test_usePathFromSettingsForToolchainPath()
empty, empty,
{}, {},
{}, {},
VersionDetection{},
false}; false};
McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}};
@@ -796,10 +810,8 @@ void McuSupportTest::test_legacy_createTargetWithToolchainPackages_data()
<< QStringList{armGccVersion, armGccNewVersion}; << QStringList{armGccVersion, armGccNewVersion};
QTest::newRow("stm32f469i") << iar_stm32f469i_metal_json << iarToolchainFilePath << iarDir QTest::newRow("stm32f469i") << iar_stm32f469i_metal_json << iarToolchainFilePath << iarDir
<< iarSetting << iarVersions; << iarSetting << iarVersions;
QTest::newRow("nxp1064") << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting QTest::newRow("iar_nxp_1064_json")
<< iarVersions; << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting << iarVersions;
QTest::newRow("nxp1064") << iar_nxp_1064_json << iarToolchainFilePath << iarDir << iarSetting
<< iarVersions;
QTest::newRow("ghs_rh850_d1m1a_baremetal_json") QTest::newRow("ghs_rh850_d1m1a_baremetal_json")
<< ghs_rh850_d1m1a_baremetal_json << greenhillToolchainFilePath << greenhillCompilerDir << ghs_rh850_d1m1a_baremetal_json << greenhillToolchainFilePath << greenhillCompilerDir
<< greenhillSetting << greenhillVersions; << greenhillSetting << greenhillVersions;
@@ -932,4 +944,156 @@ void McuSupportTest::test_legacy_createQtMCUsPackage()
QCOMPARE(qtForMCUsSDK->path().toString(), qtForMcuSdkPath); 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<QString>("json");
QTest::addColumn<QString>("versionDetectionPath");
QTest::addColumn<QString>("versionDetectionArgs");
QTest::addColumn<QString>("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<QString>("json");
QTest::addColumn<QString>("xmlElement");
QTest::addColumn<QString>("xmlAttribute");
QTest::addColumn<QString>("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 } // namespace McuSupport::Internal::Test

View File

@@ -87,6 +87,17 @@ private slots:
void test_getFullToolchainFilePathFromTarget(); void test_getFullToolchainFilePathFromTarget();
void test_legacy_getPredefinedToolchainFilePackage(); void test_legacy_getPredefinedToolchainFilePackage();
void test_legacy_createUnsupportedToolchainFilePackage(); 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_data();
void test_legacy_createBoardSdk(); void test_legacy_createBoardSdk();