forked from qt-creator/qt-creator
CMakePM: Add supprot for CMakePresets version 3
This includes Condition and toolchainFile https://cmake.org/cmake/help/v3.21/manual/cmake-presets.7.html Task-number: QTCREATORBUG-24555 Change-Id: I1026390af67b2be1aa0c3b02b654fc19442d3c89 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -1168,7 +1168,8 @@ static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString buildT
|
||||
static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArguments,
|
||||
const CMakeProject *project,
|
||||
const Kit *k,
|
||||
const Utils::Environment &env)
|
||||
const Utils::Environment &env,
|
||||
const Utils::FilePath &buildDirectory)
|
||||
|
||||
{
|
||||
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k);
|
||||
@@ -1230,6 +1231,11 @@ static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArgume
|
||||
initialArguments.append("--debug-output");
|
||||
}
|
||||
|
||||
CMakePresets::Macros::updateToolchainFile(configurePreset,
|
||||
env,
|
||||
project->projectDirectory(),
|
||||
buildDirectory);
|
||||
|
||||
// Merge the presets cache variables
|
||||
CMakeConfig cache;
|
||||
if (configurePreset.cacheVariables)
|
||||
@@ -1547,15 +1553,16 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
||||
|
||||
CMakeProject *cmakeProject = static_cast<CMakeProject *>(target->project());
|
||||
setUserConfigureEnvironmentChanges(getEnvironmentItemsFromCMakeConfigurePreset(cmakeProject, k));
|
||||
updateAndEmitConfigureEnvironmentChanged();
|
||||
|
||||
QStringList initialCMakeArguments = cmd.splitArguments();
|
||||
addCMakeConfigurePresetToInitialArguments(initialCMakeArguments,
|
||||
cmakeProject,
|
||||
k,
|
||||
configureEnvironment());
|
||||
configureEnvironment(),
|
||||
info.buildDirectory);
|
||||
m_buildSystem->setInitialCMakeArguments(initialCMakeArguments);
|
||||
m_buildSystem->setCMakeBuildType(buildType);
|
||||
updateAndEmitConfigureEnvironmentChanged();
|
||||
|
||||
setBuildPresetToBuildSteps(target);
|
||||
});
|
||||
@@ -1825,24 +1832,31 @@ void CMakeBuildConfiguration::setInitialBuildAndCleanSteps(const ProjectExplorer
|
||||
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(
|
||||
target->kit());
|
||||
|
||||
int buildSteps = 1;
|
||||
if (!presetItem.isNull()) {
|
||||
const QString presetName = presetItem.expandedValue(target->kit());
|
||||
const CMakeProject *project = static_cast<const CMakeProject *>(target->project());
|
||||
|
||||
const auto buildPresets = project->presetsData().buildPresets;
|
||||
const int count = std::count_if(buildPresets.begin(),
|
||||
buildPresets.end(),
|
||||
[presetName](const PresetsDetails::BuildPreset &preset) {
|
||||
return preset.configurePreset == presetName
|
||||
&& !preset.hidden.value();
|
||||
});
|
||||
const int count
|
||||
= std::count_if(buildPresets.begin(),
|
||||
buildPresets.end(),
|
||||
[presetName, project](const PresetsDetails::BuildPreset &preset) {
|
||||
bool enabled = true;
|
||||
if (preset.condition)
|
||||
enabled = CMakePresets::Macros::evaluatePresetCondition(
|
||||
preset, project->projectDirectory());
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||
|
||||
} else {
|
||||
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||
return preset.configurePreset == presetName
|
||||
&& !preset.hidden.value() && enabled;
|
||||
});
|
||||
if (count != 0)
|
||||
buildSteps = count;
|
||||
}
|
||||
|
||||
for (int i = 0; i < buildSteps; ++i)
|
||||
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||
|
||||
appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||
}
|
||||
|
||||
@@ -1858,10 +1872,15 @@ void CMakeBuildConfiguration::setBuildPresetToBuildSteps(const ProjectExplorer::
|
||||
const CMakeProject *project = static_cast<const CMakeProject *>(target->project());
|
||||
|
||||
const auto allBuildPresets = project->presetsData().buildPresets;
|
||||
const auto buildPresets
|
||||
= Utils::filtered(allBuildPresets, [presetName](const PresetsDetails::BuildPreset &preset) {
|
||||
return preset.configurePreset == presetName && !preset.hidden.value();
|
||||
});
|
||||
const auto buildPresets = Utils::filtered(
|
||||
allBuildPresets, [presetName, project](const PresetsDetails::BuildPreset &preset) {
|
||||
bool enabled = true;
|
||||
if (preset.condition)
|
||||
enabled = CMakePresets::Macros::evaluatePresetCondition(preset,
|
||||
project->projectDirectory());
|
||||
|
||||
return preset.configurePreset == presetName && !preset.hidden.value() && enabled;
|
||||
});
|
||||
|
||||
const QList<BuildStep *> buildStepList
|
||||
= Utils::filtered(buildSteps()->steps(), [](const BuildStep *bs) {
|
||||
|
||||
@@ -123,6 +123,11 @@ FilePaths CMakeProjectImporter::importCandidates()
|
||||
if (configPreset.hidden.value())
|
||||
continue;
|
||||
|
||||
if (configPreset.condition) {
|
||||
if (!CMakePresets::Macros::evaluatePresetCondition(configPreset, projectFilePath()))
|
||||
continue;
|
||||
}
|
||||
|
||||
const FilePath configPresetDir = m_presetsTempDir.filePath(configPreset.name);
|
||||
configPresetDir.createDir();
|
||||
candidates << configPresetDir;
|
||||
@@ -403,13 +408,15 @@ QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
auto data = std::make_unique<DirectoryData>();
|
||||
|
||||
const QString presetName = importPath.fileName();
|
||||
|
||||
PresetsDetails::ConfigurePreset configurePreset
|
||||
= Utils::findOrDefault(m_presetsData.configurePresets,
|
||||
[presetName](const PresetsDetails::ConfigurePreset &preset) {
|
||||
return preset.name == presetName;
|
||||
});
|
||||
|
||||
Environment env = Environment::systemEnvironment();
|
||||
CMakePresets::Macros::expand(configurePreset, env, projectDirectory());
|
||||
|
||||
if (configurePreset.displayName)
|
||||
data->cmakePresetDisplayname = configurePreset.displayName.value();
|
||||
else
|
||||
@@ -435,14 +442,16 @@ QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
QString binaryDir = importPath.toString();
|
||||
if (configurePreset.binaryDir) {
|
||||
binaryDir = configurePreset.binaryDir.value();
|
||||
CMakePresets::Macros::expand(configurePreset,
|
||||
Environment::systemEnvironment(),
|
||||
projectDirectory(),
|
||||
binaryDir);
|
||||
CMakePresets::Macros::expand(configurePreset, env, projectDirectory(), binaryDir);
|
||||
}
|
||||
|
||||
data->buildDirectory = Utils::FilePath::fromString(binaryDir);
|
||||
|
||||
CMakePresets::Macros::updateToolchainFile(configurePreset,
|
||||
env,
|
||||
projectDirectory(),
|
||||
data->buildDirectory);
|
||||
|
||||
const CMakeConfig cache = configurePreset.cacheVariables
|
||||
? configurePreset.cacheVariables.value()
|
||||
: CMakeConfig();
|
||||
|
||||
@@ -12,6 +12,25 @@
|
||||
|
||||
namespace CMakeProjectManager::Internal::CMakePresets::Macros {
|
||||
|
||||
QString getHostSystemName()
|
||||
{
|
||||
Utils::OsType osType = Utils::HostOsInfo::hostOs();
|
||||
|
||||
switch (osType) {
|
||||
case Utils::OsTypeWindows:
|
||||
return "Windows";
|
||||
case Utils::OsTypeLinux:
|
||||
return "Linux";
|
||||
case Utils::OsTypeMac:
|
||||
return "Darwin";
|
||||
case Utils::OsTypeOtherUnix:
|
||||
return "Unix";
|
||||
case Utils::OsTypeOther:
|
||||
return "Other";
|
||||
}
|
||||
return "Other";
|
||||
}
|
||||
|
||||
void expandAllButEnv(const PresetsDetails::ConfigurePreset &preset,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
QString &value)
|
||||
@@ -25,6 +44,8 @@ void expandAllButEnv(const PresetsDetails::ConfigurePreset &preset,
|
||||
value.replace("${presetName}", preset.name);
|
||||
if (preset.generator)
|
||||
value.replace("${generator}", preset.generator.value());
|
||||
|
||||
value.replace("${hostSystemName}", getHostSystemName());
|
||||
}
|
||||
|
||||
void expandAllButEnv(const PresetsDetails::BuildPreset &preset,
|
||||
@@ -141,6 +162,106 @@ void expand(const PresetType &preset,
|
||||
value.replace(match.captured(1), env.value(match.captured(2)));
|
||||
}
|
||||
|
||||
void updateToolchainFile(
|
||||
CMakeProjectManager::Internal::PresetsDetails::ConfigurePreset &configurePreset,
|
||||
const Utils::Environment &env,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
const Utils::FilePath &buildDirectory)
|
||||
{
|
||||
if (!configurePreset.toolchainFile)
|
||||
return;
|
||||
|
||||
QString toolchainFileName = configurePreset.toolchainFile.value();
|
||||
CMakePresets::Macros::expand(configurePreset, env, sourceDirectory, toolchainFileName);
|
||||
|
||||
// Resolve the relative path first to source and afterwards to build directory
|
||||
Utils::FilePath toolchainFile = Utils::FilePath::fromString(toolchainFileName);
|
||||
if (toolchainFile.isRelativePath()) {
|
||||
for (const auto &path : {sourceDirectory, buildDirectory}) {
|
||||
Utils::FilePath probePath = toolchainFile.resolvePath(path);
|
||||
if (probePath.exists() && probePath != path) {
|
||||
toolchainFile = probePath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!toolchainFile.exists())
|
||||
return;
|
||||
|
||||
// toolchainFile takes precedence to CMAKE_TOOLCHAIN_FILE
|
||||
CMakeConfig cache = configurePreset.cacheVariables ? configurePreset.cacheVariables.value()
|
||||
: CMakeConfig();
|
||||
|
||||
auto it = std::find_if(cache.begin(), cache.end(), [](const CMakeConfigItem &item) {
|
||||
return item.key == "CMAKE_TOOLCHAIN_FILE";
|
||||
});
|
||||
if (it != cache.end())
|
||||
it->value = toolchainFile.toString().toUtf8();
|
||||
else
|
||||
cache << CMakeConfigItem("CMAKE_TOOLCHAIN_FILE",
|
||||
CMakeConfigItem::FILEPATH,
|
||||
toolchainFile.toString().toUtf8());
|
||||
|
||||
configurePreset.cacheVariables = cache;
|
||||
}
|
||||
|
||||
template<class PresetType>
|
||||
void expandConditionValues(const PresetType &preset,
|
||||
const Utils::Environment &env,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
PresetsDetails::Condition &condition)
|
||||
{
|
||||
if (condition.isEquals() || condition.isNotEquals()) {
|
||||
if (condition.lhs)
|
||||
expand(preset, env, sourceDirectory, condition.lhs.value());
|
||||
if (condition.rhs)
|
||||
expand(preset, env, sourceDirectory, condition.rhs.value());
|
||||
}
|
||||
|
||||
if (condition.isInList() || condition.isNotInList()) {
|
||||
if (condition.string)
|
||||
expand(preset, env, sourceDirectory, condition.string.value());
|
||||
if (condition.list)
|
||||
for (QString &listValue : condition.list.value())
|
||||
expand(preset, env, sourceDirectory, listValue);
|
||||
}
|
||||
|
||||
if (condition.isMatches() || condition.isNotMatches()) {
|
||||
if (condition.string)
|
||||
expand(preset, env, sourceDirectory, condition.string.value());
|
||||
if (condition.regex)
|
||||
expand(preset, env, sourceDirectory, condition.regex.value());
|
||||
}
|
||||
|
||||
if (condition.isAnyOf() || condition.isAllOf()) {
|
||||
if (condition.conditions)
|
||||
for (PresetsDetails::Condition::ConditionPtr &c : condition.conditions.value())
|
||||
expandConditionValues(preset, env, sourceDirectory, *c);
|
||||
}
|
||||
|
||||
if (condition.isNot()) {
|
||||
if (condition.condition)
|
||||
expandConditionValues(preset, env, sourceDirectory, *condition.condition.value());
|
||||
}
|
||||
}
|
||||
|
||||
template<class PresetType>
|
||||
bool evaluatePresetCondition(const PresetType &preset, const Utils::FilePath &sourceDirectory)
|
||||
{
|
||||
if (!preset.condition)
|
||||
return true;
|
||||
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
expand(preset, env, sourceDirectory);
|
||||
|
||||
PresetsDetails::Condition condition = preset.condition.value();
|
||||
expandConditionValues(preset, env, sourceDirectory, condition);
|
||||
|
||||
return condition.evaluate();
|
||||
}
|
||||
|
||||
|
||||
// Expand for PresetsDetails::ConfigurePreset
|
||||
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
|
||||
Utils::Environment &env,
|
||||
@@ -155,6 +276,9 @@ template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::Conf
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
QString &value);
|
||||
|
||||
template bool evaluatePresetCondition<PresetsDetails::ConfigurePreset>(
|
||||
const PresetsDetails::ConfigurePreset &preset, const Utils::FilePath &sourceDirectory);
|
||||
|
||||
// Expand for PresetsDetails::BuildPreset
|
||||
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
|
||||
Utils::Environment &env,
|
||||
@@ -169,4 +293,7 @@ template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPre
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
QString &value);
|
||||
|
||||
template bool evaluatePresetCondition<PresetsDetails::BuildPreset>(
|
||||
const PresetsDetails::BuildPreset &preset, const Utils::FilePath &sourceDirectory);
|
||||
|
||||
} // namespace CMakeProjectManager::Internal::CMakePresets::Macros
|
||||
|
||||
@@ -12,6 +12,10 @@ class FilePath;
|
||||
|
||||
namespace CMakeProjectManager::Internal {
|
||||
|
||||
namespace PresetsDetails {
|
||||
class ConfigurePreset;
|
||||
}
|
||||
|
||||
namespace CMakePresets::Macros {
|
||||
/**
|
||||
* Expands the CMakePresets Macros using Utils::Environment as target and source for parent environment values.
|
||||
@@ -40,6 +44,22 @@ void expand(const PresetType &preset,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
QString &value);
|
||||
|
||||
/**
|
||||
* Updates the cacheVariables parameter of the configurePreset with the expandned toolchainFile parameter.
|
||||
* Including macro expansion and relative paths resolving.
|
||||
*/
|
||||
void updateToolchainFile(PresetsDetails::ConfigurePreset &configurePreset,
|
||||
const Utils::Environment &env,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
const Utils::FilePath &buildDirectory);
|
||||
|
||||
/**
|
||||
* Expands the condition values and then evaluates the condition object of the preset and returns
|
||||
* the boolean result.
|
||||
*/
|
||||
template<class PresetType>
|
||||
bool evaluatePresetCondition(const PresetType &preset, const Utils::FilePath &sourceDirectory);
|
||||
|
||||
} // namespace CMakePresets::Macros
|
||||
|
||||
} // namespace CMakeProjectManager::Internal
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "presetsparser.h"
|
||||
#include "utils/algorithm.h"
|
||||
|
||||
#include "cmakeprojectmanagertr.h"
|
||||
|
||||
@@ -34,6 +35,102 @@ bool parseCMakeMinimumRequired(const QJsonValue &jsonValue, QVersionNumber &vers
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<PresetsDetails::Condition> parseCondition(const QJsonValue &jsonValue)
|
||||
{
|
||||
std::optional<PresetsDetails::Condition> condition;
|
||||
|
||||
if (jsonValue.isUndefined())
|
||||
return condition;
|
||||
|
||||
condition = PresetsDetails::Condition();
|
||||
|
||||
if (jsonValue.isNull()) {
|
||||
condition->type = "null";
|
||||
return condition;
|
||||
}
|
||||
|
||||
if (jsonValue.isBool()) {
|
||||
condition->type = "const";
|
||||
condition->constValue = jsonValue.toBool();
|
||||
return condition;
|
||||
}
|
||||
|
||||
if (!jsonValue.isObject())
|
||||
return condition;
|
||||
|
||||
QJsonObject object = jsonValue.toObject();
|
||||
QString type = object.value("type").toString();
|
||||
if (type.isEmpty())
|
||||
return condition;
|
||||
|
||||
if (type == "const") {
|
||||
condition->type = type;
|
||||
condition->constValue = object.value("const").toBool();
|
||||
return condition;
|
||||
}
|
||||
|
||||
for (const auto &equals : {QString("equals"), QString("notEquals")}) {
|
||||
if (type == equals) {
|
||||
condition->type = equals;
|
||||
condition->lhs = object.value("lhs").toString();
|
||||
condition->rhs = object.value("rhs").toString();
|
||||
}
|
||||
}
|
||||
if (!condition->type.isEmpty())
|
||||
return condition;
|
||||
|
||||
for (const auto &inList : {QString("inList"), QString("notInList")}) {
|
||||
if (type == inList) {
|
||||
condition->type = inList;
|
||||
condition->string = object.value("string").toString();
|
||||
if (object.value("list").isArray()) {
|
||||
condition->list = QStringList();
|
||||
const QJsonArray listArray = object.value("list").toArray();
|
||||
for (const QJsonValue &listValue : listArray)
|
||||
condition->list.value() << listValue.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!condition->type.isEmpty())
|
||||
return condition;
|
||||
|
||||
for (const auto &matches : {QString("matches"), QString("notMatches")}) {
|
||||
if (type == matches) {
|
||||
condition->type = matches;
|
||||
condition->string = object.value("string").toString();
|
||||
condition->regex = object.value("regex").toString();
|
||||
}
|
||||
}
|
||||
if (!condition->type.isEmpty())
|
||||
return condition;
|
||||
|
||||
for (const auto &anyOf : {QString("anyOf"), QString("allOf")}) {
|
||||
if (type == anyOf) {
|
||||
condition->type = anyOf;
|
||||
if (object.value("conditions").isArray()) {
|
||||
condition->conditions = std::vector<PresetsDetails::Condition::ConditionPtr>();
|
||||
const QJsonArray conditionsArray = object.value("conditions").toArray();
|
||||
for (const QJsonValue &conditionsValue : conditionsArray) {
|
||||
condition->conditions.value().emplace_back(
|
||||
std::make_shared<PresetsDetails::Condition>(
|
||||
parseCondition(conditionsValue).value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!condition->type.isEmpty())
|
||||
return condition;
|
||||
|
||||
if (type == "not") {
|
||||
condition->type = type;
|
||||
condition->condition = std::make_shared<PresetsDetails::Condition>(
|
||||
parseCondition(object.value("condition")).value());
|
||||
return condition;
|
||||
}
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
bool parseConfigurePresets(const QJsonValue &jsonValue,
|
||||
QList<PresetsDetails::ConfigurePreset> &configurePresets)
|
||||
{
|
||||
@@ -68,6 +165,10 @@ bool parseConfigurePresets(const QJsonValue &jsonValue,
|
||||
preset.inherits.value() << inheritsValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (object.contains("condition"))
|
||||
preset.condition = parseCondition(object.value("condition"));
|
||||
|
||||
if (object.contains("displayName"))
|
||||
preset.displayName = object.value("displayName").toString();
|
||||
if (object.contains("description"))
|
||||
@@ -76,6 +177,8 @@ bool parseConfigurePresets(const QJsonValue &jsonValue,
|
||||
preset.generator = object.value("generator").toString();
|
||||
if (object.contains("binaryDir"))
|
||||
preset.binaryDir = object.value("binaryDir").toString();
|
||||
if (object.contains("toolchainFile"))
|
||||
preset.toolchainFile = object.value("toolchainFile").toString();
|
||||
if (object.contains("cmakeExecutable"))
|
||||
preset.cmakeExecutable = object.value("cmakeExecutable").toString();
|
||||
|
||||
@@ -218,6 +321,10 @@ bool parseBuildPresets(const QJsonValue &jsonValue,
|
||||
preset.inherits.value() << inheritsValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (object.contains("condition"))
|
||||
preset.condition = parseCondition(object.value("condition"));
|
||||
|
||||
if (object.contains("displayName"))
|
||||
preset.displayName = object.value("displayName").toString();
|
||||
if (object.contains("description"))
|
||||
@@ -334,6 +441,9 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage
|
||||
|
||||
void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other)
|
||||
{
|
||||
if (!condition && other.condition && !other.condition.value().isNull())
|
||||
condition = other.condition;
|
||||
|
||||
if (!vendor && other.vendor)
|
||||
vendor = other.vendor;
|
||||
|
||||
@@ -346,6 +456,9 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other)
|
||||
if (!toolset && other.toolset)
|
||||
toolset = other.toolset;
|
||||
|
||||
if (!toolchainFile && other.toolchainFile)
|
||||
toolchainFile = other.toolchainFile;
|
||||
|
||||
if (!binaryDir && other.binaryDir)
|
||||
binaryDir = other.binaryDir;
|
||||
|
||||
@@ -370,6 +483,9 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other)
|
||||
|
||||
void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other)
|
||||
{
|
||||
if (!condition && other.condition && !other.condition.value().isNull())
|
||||
condition = other.condition;
|
||||
|
||||
if (!vendor && other.vendor)
|
||||
vendor = other.vendor;
|
||||
|
||||
@@ -401,4 +517,46 @@ void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other)
|
||||
nativeToolOptions = other.nativeToolOptions;
|
||||
}
|
||||
|
||||
bool PresetsDetails::Condition::evaluate() const
|
||||
{
|
||||
if (isNull())
|
||||
return true;
|
||||
|
||||
if (isConst() && constValue)
|
||||
return constValue.value();
|
||||
|
||||
if (isEquals() && lhs && rhs)
|
||||
return lhs.value() == rhs.value();
|
||||
|
||||
if (isNotEquals() && lhs && rhs)
|
||||
return lhs.value() != rhs.value();
|
||||
|
||||
if (isInList() && string && list)
|
||||
return list.value().contains(string.value());
|
||||
|
||||
if (isNotInList() && string && list)
|
||||
return !list.value().contains(string.value());
|
||||
|
||||
if (isMatches() && string && regex) {
|
||||
QRegularExpression qRegex(regex.value());
|
||||
return qRegex.match(string.value()).hasMatch();
|
||||
}
|
||||
|
||||
if (isNotMatches() && string && regex) {
|
||||
QRegularExpression qRegex(regex.value());
|
||||
return !qRegex.match(string.value()).hasMatch();
|
||||
}
|
||||
|
||||
if (isAnyOf() && conditions)
|
||||
return Utils::anyOf(conditions.value(), [](const ConditionPtr &c) { return c->evaluate(); });
|
||||
|
||||
if (isAllOf() && conditions)
|
||||
return Utils::allOf(conditions.value(), [](const ConditionPtr &c) { return c->evaluate(); });
|
||||
|
||||
if (isNot() && condition)
|
||||
return !condition.value()->evaluate();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // CMakeProjectManager::Internal
|
||||
|
||||
@@ -43,6 +43,47 @@ public:
|
||||
std::optional<bool> find = false;
|
||||
};
|
||||
|
||||
class Condition {
|
||||
public:
|
||||
QString type;
|
||||
|
||||
bool isNull() const { return type == "null"; }
|
||||
bool isConst() const { return type == "const"; }
|
||||
bool isEquals() const { return type == "equals"; }
|
||||
bool isNotEquals() const { return type == "notEquals"; }
|
||||
bool isInList() const { return type == "inList"; }
|
||||
bool isNotInList() const { return type == "notInList"; }
|
||||
bool isMatches() const { return type == "matches"; }
|
||||
bool isNotMatches() const { return type == "notMatches"; }
|
||||
bool isAnyOf() const { return type == "anyOf"; }
|
||||
bool isAllOf() const { return type == "allOf"; }
|
||||
bool isNot() const { return type == "not"; }
|
||||
|
||||
bool evaluate() const;
|
||||
|
||||
// const
|
||||
std::optional<bool> constValue;
|
||||
|
||||
// equals, notEquals
|
||||
std::optional<QString> lhs;
|
||||
std::optional<QString> rhs;
|
||||
|
||||
// inList, notInList
|
||||
std::optional<QString> string;
|
||||
std::optional<QStringList> list;
|
||||
|
||||
// matches, notMatches
|
||||
std::optional<QString> regex;
|
||||
|
||||
using ConditionPtr = std::shared_ptr<Condition>;
|
||||
|
||||
// anyOf, allOf
|
||||
std::optional<std::vector<ConditionPtr>> conditions;
|
||||
|
||||
// not
|
||||
std::optional<ConditionPtr> condition;
|
||||
};
|
||||
|
||||
class ConfigurePreset {
|
||||
public:
|
||||
void inheritFrom(const ConfigurePreset &other);
|
||||
@@ -50,12 +91,14 @@ public:
|
||||
QString name;
|
||||
std::optional<bool> hidden = false;
|
||||
std::optional<QStringList> inherits;
|
||||
std::optional<Condition> condition;
|
||||
std::optional<QHash<QString, QString>> vendor;
|
||||
std::optional<QString> displayName;
|
||||
std::optional<QString> description;
|
||||
std::optional<QString> generator;
|
||||
std::optional<ValueStrategyPair> architecture;
|
||||
std::optional<ValueStrategyPair> toolset;
|
||||
std::optional<QString> toolchainFile;
|
||||
std::optional<QString> binaryDir;
|
||||
std::optional<QString> cmakeExecutable;
|
||||
std::optional<CMakeConfig> cacheVariables;
|
||||
@@ -72,6 +115,7 @@ public:
|
||||
QString name;
|
||||
std::optional<bool> hidden = false;
|
||||
std::optional<QStringList> inherits;
|
||||
std::optional<Condition> condition;
|
||||
std::optional<QHash<QString, QString>> vendor;
|
||||
std::optional<QString> displayName;
|
||||
std::optional<QString> description;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"version": 2,
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 20,
|
||||
"minor": 21,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
@@ -15,6 +15,11 @@
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "c:/Qt/Tools/mingw1120_64/bin;$penv{PATH}"
|
||||
},
|
||||
@@ -36,8 +41,29 @@
|
||||
"architecture" : {
|
||||
"value": "x64"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/msvc2019_64"
|
||||
"toolchainFile" : "c:/Qt/6.3.2/msvc2019_64/lib/cmake/Qt6/qt.toolchain.cmake",
|
||||
"condition" : {
|
||||
"type": "not",
|
||||
"condition": {
|
||||
"type": "notEquals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "$env{HOST_SYSTEM_NAME}"
|
||||
}
|
||||
},
|
||||
"environment" : {
|
||||
"HOST_SYSTEM_NAME": "Windows"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc",
|
||||
"displayName": "Linux GCC",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-${presetName}",
|
||||
"toolchainFile" : "$penv{HOME}/Qt/6.3.2/gcc_64/lib/cmake/Qt6/qt.toolchain.cmake",
|
||||
"condition" : {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user