CMakePM: update CMakePresets macro replacement function

Moved to a handcrafted function instead of using regex.

This way the Visual C++ Ninja only preset can be processed.

Change-Id: I9b303ee1765db05544d81db7d3b8d9e5223f5f42
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Cristian Adam
2022-09-30 15:01:58 +02:00
parent 6644927c4e
commit ab7a472b94
3 changed files with 122 additions and 33 deletions

View File

@@ -8,8 +8,6 @@
#include <utils/filepath.h>
#include <utils/hostosinfo.h>
#include <QRegularExpression>
namespace CMakeProjectManager::Internal::CMakePresets::Macros {
QString getHostSystemName()
@@ -61,6 +59,48 @@ void expandAllButEnv(const PresetsDetails::BuildPreset &preset,
value.replace("${presetName}", preset.name);
}
QString expandMacroEnv(const QString &macroPrefix,
const QString &value,
const std::function<QString(const QString &)> &op)
{
const QString startToken = QString("$%1{").arg(macroPrefix);
const QString endToken = QString("}");
auto findMacro = [startToken,
endToken](const QString &str, qsizetype *pos, QString *ret) -> qsizetype {
forever {
qsizetype openPos = str.indexOf(startToken, *pos);
if (openPos < 0)
return 0;
qsizetype varPos = openPos + startToken.length();
qsizetype endPos = str.indexOf(endToken, varPos + 1);
if (endPos < 0)
return 0;
*ret = str.mid(varPos, endPos - varPos);
*pos = openPos;
return endPos - openPos + endToken.length();
}
};
QString result = value;
QString macroName;
bool done = true;
do {
done = true;
for (qsizetype pos = 0; int len = findMacro(result, &pos, &macroName);) {
result.replace(pos, len, op(macroName));
pos += macroName.length();
done = false;
}
} while (!done);
return result;
}
template<class PresetType>
void expand(const PresetType &preset,
Utils::Environment &env,
@@ -73,14 +113,9 @@ void expand(const PresetType &preset,
QString value = it->second;
expandAllButEnv(preset, sourceDirectory, value);
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) {
if (match.captured(2) != key)
value.replace(match.captured(1), presetEnv.value(match.captured(2)));
else
value.replace(match.captured(1), "");
}
value = expandMacroEnv("env", value, [presetEnv](const QString &macroName) {
return presetEnv.value(macroName);
});
QString sep;
bool append = true;
@@ -92,9 +127,9 @@ void expand(const PresetType &preset,
value.replace("$penv{PATH}", "", Qt::CaseInsensitive);
}
QRegularExpression penvRegex(R"((\$penv\{(\w+)\}))");
for (const QRegularExpressionMatch &match : penvRegex.globalMatch(value))
value.replace(match.captured(1), env.value(match.captured(2)));
value = expandMacroEnv("penv", value, [env](const QString &macroName) {
return env.value(macroName);
});
if (append)
env.appendOrSet(key, value, sep);
@@ -116,14 +151,9 @@ void expand(const PresetType &preset,
QString value = it->second;
expandAllButEnv(preset, sourceDirectory, value);
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) {
if (match.captured(2) != key)
value.replace(match.captured(1), presetEnv.value(match.captured(2)));
else
value.replace(match.captured(1), "");
}
value = expandMacroEnv("env", value, [presetEnv](const QString &macroName) {
return presetEnv.value(macroName);
});
auto operation = Utils::EnvironmentItem::Operation::SetEnabled;
if (key.compare("PATH", Qt::CaseInsensitive) == 0) {
@@ -134,9 +164,9 @@ void expand(const PresetType &preset,
value.replace("$penv{PATH}", "", Qt::CaseInsensitive);
}
QRegularExpression penvRegex(R"((\$penv\{(\w+)\}))");
for (const QRegularExpressionMatch &match : penvRegex.globalMatch(value))
value.replace(match.captured(1), QString("${%1}").arg(match.captured(2)));
value = expandMacroEnv("penv", value, [](const QString &macroName) {
return QString("${%1}").arg(macroName);
});
envItems.emplace_back(Utils::EnvironmentItem(key, value, operation));
}
@@ -153,13 +183,13 @@ void expand(const PresetType &preset,
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
: QHash<QString, QString>();
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value))
value.replace(match.captured(1), presetEnv.value(match.captured(2)));
value = expandMacroEnv("env", value, [presetEnv](const QString &macroName) {
return presetEnv.value(macroName);
});
QRegularExpression penvRegex(R"((\$penv\{(\w+)\}))");
for (const QRegularExpressionMatch &match : penvRegex.globalMatch(value))
value.replace(match.captured(1), env.value(match.captured(2)));
value = expandMacroEnv("penv", value, [env](const QString &macroName) {
return env.value(macroName);
});
}
void updateToolchainFile(
@@ -261,7 +291,6 @@ bool evaluatePresetCondition(const PresetType &preset, const Utils::FilePath &so
return condition.evaluate();
}
// Expand for PresetsDetails::ConfigurePreset
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
Utils::Environment &env,

View File

@@ -54,6 +54,34 @@
"HOST_SYSTEM_NAME": "Windows"
}
},
{
"name": "visualc-ninja",
"displayName": "Visual C++ 2019 x64 Ninja",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build-${presetName}",
"toolchainFile" : "c:/Qt/6.3.2/msvc2019_64/lib/cmake/Qt6/qt.toolchain.cmake",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"environment" : {
"VCToolsVersion": "14.29.30133",
"WindowsSDKVersion" : "10.0.22000.0",
"VCArch": "x64",
"VCToolsInstallDir": "$penv{ProgramFiles(x86)}/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/$env{VCToolsVersion}",
"WindowsSdkDir" : "$penv{ProgramFiles(x86)}/Windows Kits/10",
"WindowsSdkIncVerDir": "$env{WindowsSdkDir}/Include/$env{WindowsSDKVersion}",
"WindowsSdkLibVerDir": "$env{WindowsSdkDir}/Lib/$env{WindowsSDKVersion}",
"INCLUDE": "$env{VCToolsInstallDir}/ATLMFC/include;$env{VCToolsInstallDir}/include;$env{WindowsSdkIncVerDir}/ucrt;$env{WindowsSdkIncVerDir}/shared;$env{WindowsSdkIncVerDir}/um;$env{WindowsSdkIncVerDir}/winrt;$env{WindowsSdkIncVerDir}/cppwinrt",
"LIB": "$env{VCToolsInstallDir}/ATLMFC/lib/$env{VCArch};$env{VCToolsInstallDir}/lib/$env{VCArch};$env{WindowsSdkLibVerDir}/ucrt/$env{VCArch};$env{WindowsSdkLibVerDir}/um/$env{VCArch}",
"PATH": "$env{VCToolsInstallDir}/bin/HostX64/$env{VCArch};$env{WindowsSdkDir}/bin/$env{WindowsSDKVersion}/$env{VCArch};$penv{PATH}"
}
},
{
"name": "linux-gcc",
"displayName": "Linux GCC",
@@ -95,6 +123,10 @@
"name": "visualc-relwithdebinfo",
"inherits": "visualc-debug",
"configuration": "RelWithDebInfo"
},
{
"name": "visualc-ninja",
"configurePreset": "visualc-ninja"
}
]
}

View File

@@ -13,8 +13,36 @@
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar"/>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>140</x>
<y>200</y>
<width>441</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>22</pointsize>
</font>
</property>
<property name="text">
<string>CMakePresets are cool!</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>