diff --git a/src/plugins/mcusupport/mcuhelpers.h b/src/plugins/mcusupport/mcuhelpers.h index 0c6baf83af0..1054e87eea9 100644 --- a/src/plugins/mcusupport/mcuhelpers.h +++ b/src/plugins/mcusupport/mcuhelpers.h @@ -14,4 +14,18 @@ struct McuTargetDescription; McuTarget::OS deduceOperatingSystem(const McuTargetDescription &); QString removeRtosSuffix(const QString &environmentVariable); +template +class asKeyValueRange +{ +public: + asKeyValueRange(T &data) + : m_data{data} + {} + auto begin() { return m_data.keyValueBegin(); } + auto end() { return m_data.keyValueEnd(); } + +private: + T &m_data; +}; + } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index edd7ac13bfc..9dead1d5550 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -3,6 +3,7 @@ #include "mcusupportoptions.h" +#include "mcuhelpers.h" #include "mcukitmanager.h" #include "mcupackage.h" #include "mcusupportconstants.h" @@ -16,16 +17,49 @@ #include #include #include +#include #include #include #include #include +#include + using namespace Utils; namespace McuSupport::Internal { +Macros *McuSdkRepository::globalMacros() +{ + static Macros macros; + return ¯os; +} + +void McuSdkRepository::expandVariables() +{ + auto macroExpander = getMacroExpander(); + for (const auto &package : std::as_const(packages)) + package->setPath(macroExpander->expand(package->path())); +} + +MacroExpanderPtr McuSdkRepository::getMacroExpander() +{ + auto macroExpander = std::make_shared(); + + //register the macros + for (const auto &package : std::as_const(packages)) { + macroExpander->registerVariable(package->cmakeVariableName().toLocal8Bit(), + package->label(), + [package] { return package->path().toString(); }); + } + + for (auto [key, macro] : asKeyValueRange(*globalMacros())) + macroExpander->registerVariable(key.toLocal8Bit(), "QtMCUs Macro", macro); + + return macroExpander; +} + McuSupportOptions::McuSupportOptions(const SettingsHandler::Ptr &settingsHandler, QObject *parent) : QObject(parent) , qtForMCUsSdkPackage(createQtForMCUsPackage(settingsHandler)) @@ -93,8 +127,15 @@ bool McuSupportOptions::isLegacyVersion(const QVersionNumber &version) return version < newVersion; } -void McuSupportOptions::setQulDir(const FilePath &) +void McuSupportOptions::setQulDir(const FilePath &path) { + //register the Qt installation directory containing Qul dir + auto qtPath = (path / "../..").cleanPath(); + if (qtPath.exists()) { + McuSdkRepository::globalMacros()->insert("QtDir", [qtPathString = qtPath.path()] { + return qtPathString; + }); + } qtForMCUsSdkPackage->updateStatus(); if (qtForMCUsSdkPackage->isValidStatus()) sdkRepository = targetsAndPackages(qtForMCUsSdkPackage, settingsHandler); diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 945c748dff0..220fc54f125 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -8,6 +8,7 @@ #include "settingshandler.h" #include +#include #include #include @@ -30,11 +31,19 @@ namespace Internal { class McuAbstractPackage; +using MacroExpanderPtr = std::shared_ptr; +using Macros = QHash; + class McuSdkRepository final { public: Targets mcuTargets; Packages packages; + + void expandVariables(); + MacroExpanderPtr getMacroExpander(); + + static Macros *globalMacros(); }; class McuSupportOptions final : public QObject diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index f728851774f..556dfd0e216 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -289,7 +289,7 @@ void McuSupportOptionsWidget::apply() bool pathsChanged = false; m_settingsHandler->setAutomaticKitCreation(m_options.automaticKitCreationEnabled()); - McuTargetFactory::expandVariables(m_options.sdkRepository.packages); + m_options.sdkRepository.expandVariables(); QMessageBox warningPopup(QMessageBox::Icon::Warning, Tr::tr("Warning"), diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index a6959917e66..76f24206797 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -591,7 +591,11 @@ McuSdkRepository targetsFromDescriptions(const QList &desc mcuPackages.insert(package); } } - return McuSdkRepository{mcuTargets, mcuPackages}; + + McuSdkRepository repo{mcuTargets, mcuPackages}; + repo.expandVariables(); + + return repo; } FilePath kitsPath(const FilePath &qtMcuSdkPath) diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index ae79aeee359..6f5be2a1026 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -4,6 +4,7 @@ #include "mcutargetfactory.h" #include "mcuhelpers.h" #include "mcupackage.h" +#include "mcusupport_global.h" #include "mcusupportplugin.h" #include "mcusupportversiondetection.h" #include "mcutarget.h" @@ -56,18 +57,6 @@ static void removeEmptyPackages(Packages &packages) } } -void McuTargetFactory::expandVariables(Packages &packages) -{ - Utils::MacroExpander macroExpander; - for (const auto &package : packages) { - macroExpander.registerVariable(package->cmakeVariableName().toLocal8Bit(), - package->label(), - [package] { return package->path().toString(); }); - } - for (const auto &package : packages) - package->setPath(macroExpander.expand(package->path())); -} - McuTargetFactory::McuTargetFactory(const SettingsHandler::Ptr &settingsHandler) : settingsHandler{settingsHandler} {} @@ -94,7 +83,6 @@ QPair McuTargetFactory::createTargets(const McuTargetDescript targetPackages.unite({toolchainFile}); removeEmptyPackages(targetPackages); - expandVariables(targetPackages); packages.unite(targetPackages); diff --git a/src/plugins/mcusupport/mcutargetfactory.h b/src/plugins/mcusupport/mcutargetfactory.h index bb18ea40a39..94451b4c07f 100644 --- a/src/plugins/mcusupport/mcutargetfactory.h +++ b/src/plugins/mcusupport/mcutargetfactory.h @@ -22,7 +22,6 @@ public: Packages createPackages(const McuTargetDescription &); McuToolChainPackage *createToolchain(const McuTargetDescription::Toolchain &, const Utils::FilePath &sourceFile = Utils::FilePath()); McuPackagePtr createPackage(const PackageDescription &); - static void expandVariables(Packages &packages); private: SettingsHandler::Ptr settingsHandler; diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 090ed89cd5c..ca28f925bb6 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -196,6 +196,11 @@ const McuTargetDescription::Platform platformDescription{id, const Id cxxLanguageId{ProjectExplorer::Constants::CXX_LANGUAGE_ID}; } // namespace +//Expand variables in a tested {targets, packages} pair +auto expandTargetsAndPackages = [](Targets &targets, Packages &packages) { + McuSdkRepository{targets, packages}.expandVariables(); +}; + void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) { ProjectExplorer::ToolChainFactory toolchainFactory; @@ -676,7 +681,7 @@ void McuSupportTest::test_legacy_createPackagesWithCorrespondingSettings() { QFETCH(QString, json); const McuTargetDescription description = parseDescriptionJson(json.toLocal8Bit()); - const auto [targets, packages]{ + auto [targets, packages]{ targetsFromDescriptions({description}, settingsMockPtr, sdkPackagePtr, runLegacy)}; Q_UNUSED(targets); @@ -701,7 +706,8 @@ void McuSupportTest::test_createTargets() true}; targetDescription.toolchain.id = armGcc; - const auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); QCOMPARE(targets.size(), 1); const McuTargetPtr target{targets.at(0)}; @@ -1154,7 +1160,8 @@ void McuSupportTest::test_createFreeRtosPackage() EXPECT_CALL(*settingsMockPtr, getPath(targetDescription.boardSdk.envVar, _, _)) .WillRepeatedly(Return(FilePath::fromString(boardSdkDir))); - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto freeRtos = findOrDefault(packages, [](const McuPackagePtr &pkg) { return (pkg->cmakeVariableName() == freeRtosCMakeVar); @@ -1379,7 +1386,8 @@ void McuSupportTest::test_resolveEnvironmentVariablesInDefaultPath() toochainFileDescription.defaultPath = FilePath::fromUserInput(toolchainFileDefaultPath); targetDescription.toolchain.file = toochainFileDescription; - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto qtForMCUPkg = findOrDefault(packages, [](const McuPackagePtr &pkg) { return pkg->environmentVariableName() == QUL_ENV_VAR; }); @@ -1413,7 +1421,8 @@ void McuSupportTest::test_resolveCmakeVariablesInDefaultPath() toochainFileDescription.defaultPath = FilePath::fromUserInput(toolchainFileDefaultPath); targetDescription.toolchain.file = toochainFileDescription; - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto qtForMCUPkg = findOrDefault(packages, [](const McuPackagePtr &pkg) { return pkg->cmakeVariableName() == QUL_CMAKE_VAR; }); @@ -1541,6 +1550,7 @@ void McuSupportTest::test_createThirdPartyPackage() .WillOnce(Return(FilePath::fromUserInput(path))); auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + expandTargetsAndPackages(targets, packages); auto thirdPartyPackage = findOrDefault(packages, [&setting](const McuPackagePtr &pkg) { return (pkg->settingsKey() == setting); @@ -1588,6 +1598,7 @@ void McuSupportTest::test_createJLink3rdPartyPackage() .WillOnce(Return(FilePath::fromUserInput(jlinkPath))); auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + expandTargetsAndPackages(targets, packages); auto thirdPartyPackage = findOrDefault(packages, [](const McuPackagePtr &pkg) { return (pkg->settingsKey() == jlinkSetting); @@ -1653,7 +1664,6 @@ void McuSupportTest::test_nonemptyVersionDetector() // pkgDesc.versionDetection.xmlElement left empty // pkgDesc.versionDetection.xmlAttribute left empty pkgDesc.shouldAddToSystemPath = false; - const auto package = targetFactory.createPackage(pkgDesc); QVERIFY(package->getVersionDetector() != nullptr); QCOMPARE(typeid(*package->getVersionDetector()).name(), @@ -1686,7 +1696,8 @@ void McuSupportTest::test_emptyVersionDetector() void McuSupportTest::test_emptyVersionDetectorFromJson() { const auto targetDescription = parseDescriptionJson(armgcc_mimxrt1050_evk_freertos_json); - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto freeRtos = findOrDefault(packages, [](const McuPackagePtr &pkg) { return (pkg->cmakeVariableName() == freeRtosCMakeVar);