diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/QtDialog/CMakeSetupDialog.cxx | 4 | ||||
-rw-r--r-- | Source/QtDialog/QCMake.cxx | 28 | ||||
-rw-r--r-- | Source/QtDialog/QCMakePreset.cxx | 17 | ||||
-rw-r--r-- | Source/QtDialog/QCMakePreset.h | 3 | ||||
-rw-r--r-- | Source/cmCMakePresetsFile.cxx | 362 | ||||
-rw-r--r-- | Source/cmCMakePresetsFile.h | 29 | ||||
-rw-r--r-- | Source/cmake.cxx | 25 |
7 files changed, 299 insertions, 169 deletions
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 7a04daa..a15614d 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -859,8 +859,10 @@ bool CMakeSetupDialog::setupFirstConfigure() if (presetData.isValid()) { auto preset = presetData.value<QCMakePreset>(); dialog.setCurrentGenerator(preset.generator); - if (preset.setGenConfig) { + if (preset.setArchitecture) { dialog.setPlatform(preset.architecture); + } + if (preset.setToolset) { dialog.setToolset(preset.toolset); } dialog.setCompilerOption(CompilerOption::DefaultNative); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 9017a63..2f41f70 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -157,8 +157,8 @@ void QCMake::setPreset(const QString& name, bool setBinary) if (!name.isNull()) { std::string presetName(name.toLocal8Bit()); - auto const& preset = this->CMakePresetsFile.Presets[presetName]; - auto expandedPreset = this->CMakePresetsFile.ExpandMacros(preset); + auto const& expandedPreset = + this->CMakePresetsFile.Presets[presetName].Expanded; if (expandedPreset) { if (setBinary) { QString binaryDir = @@ -420,8 +420,7 @@ QCMakePropertyList QCMake::properties() const if (!this->PresetName.isNull()) { std::string presetName(this->PresetName.toLocal8Bit()); - auto p = this->CMakePresetsFile.ExpandMacros( - this->CMakePresetsFile.Presets.at(presetName)); + auto const& p = this->CMakePresetsFile.Presets.at(presetName).Expanded; if (p) { for (auto const& v : p->CacheVariables) { if (!v.second) { @@ -537,7 +536,8 @@ void QCMake::loadPresets() QVector<QCMakePreset> presets; for (auto const& name : this->CMakePresetsFile.PresetOrder) { - auto const& p = this->CMakePresetsFile.Presets[name]; + auto const& it = this->CMakePresetsFile.Presets[name]; + auto const& p = it.Unexpanded; if (p.Hidden) { continue; } @@ -551,15 +551,17 @@ void QCMake::loadPresets() preset.generator = std::move(QString::fromLocal8Bit(p.Generator.data())); preset.architecture = std::move(QString::fromLocal8Bit(p.Architecture.data())); + preset.setArchitecture = !p.ArchitectureStrategy || + p.ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data())); - preset.setGenConfig = !p.GeneratorConfig || - p.GeneratorConfig == cmCMakePresetsFile::CMakeGeneratorConfig::Default; - preset.enabled = std::find_if(this->AvailableGenerators.begin(), - this->AvailableGenerators.end(), - [&p](const cmake::GeneratorInfo& g) { - return g.name == p.Generator; - }) != this->AvailableGenerators.end() && - this->CMakePresetsFile.ExpandMacros(p); + preset.setToolset = !p.ToolsetStrategy || + p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; + preset.enabled = it.Expanded && + std::find_if(this->AvailableGenerators.begin(), + this->AvailableGenerators.end(), + [&p](const cmake::GeneratorInfo& g) { + return g.name == p.Generator; + }) != this->AvailableGenerators.end(); presets.push_back(preset); } emit this->presetsChanged(presets); diff --git a/Source/QtDialog/QCMakePreset.cxx b/Source/QtDialog/QCMakePreset.cxx index b10cf07..176f532 100644 --- a/Source/QtDialog/QCMakePreset.cxx +++ b/Source/QtDialog/QCMakePreset.cxx @@ -6,8 +6,9 @@ bool operator==(const QCMakePreset& lhs, const QCMakePreset& rhs) { return lhs.name == rhs.name && lhs.displayName == rhs.displayName && lhs.description == rhs.description && lhs.generator == rhs.generator && - lhs.architecture == rhs.architecture && lhs.toolset == rhs.toolset && - lhs.setGenConfig == rhs.setGenConfig && lhs.enabled == rhs.enabled; + lhs.architecture == rhs.architecture && + lhs.setArchitecture == rhs.setArchitecture && lhs.toolset == rhs.toolset && + lhs.setToolset == rhs.setToolset && lhs.enabled == rhs.enabled; } bool operator!=(const QCMakePreset& lhs, const QCMakePreset& rhs) @@ -27,11 +28,13 @@ bool operator<(const QCMakePreset& lhs, const QCMakePreset& rhs) (lhs.generator == rhs.generator && (lhs.architecture < rhs.architecture || (lhs.architecture == rhs.architecture && - (lhs.toolset < rhs.toolset || - (lhs.toolset == rhs.toolset && - (lhs.setGenConfig < rhs.setGenConfig || - (lhs.setGenConfig == rhs.setGenConfig && - (lhs.enabled < rhs.enabled)))))))))))))); + (lhs.setArchitecture < rhs.setArchitecture || + (lhs.setArchitecture == rhs.setArchitecture && + (lhs.toolset < rhs.toolset || + (lhs.toolset == rhs.toolset && + (lhs.setToolset < rhs.setToolset || + (lhs.setToolset == rhs.setToolset && + (lhs.enabled < rhs.enabled)))))))))))))))); } bool operator<=(const QCMakePreset& lhs, const QCMakePreset& rhs) diff --git a/Source/QtDialog/QCMakePreset.h b/Source/QtDialog/QCMakePreset.h index 93d70d8..1609fcb 100644 --- a/Source/QtDialog/QCMakePreset.h +++ b/Source/QtDialog/QCMakePreset.h @@ -15,8 +15,9 @@ public: QString description; QString generator; QString architecture; + bool setArchitecture; QString toolset; - bool setGenConfig; + bool setToolset; bool enabled; }; diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsFile.cxx index 90a0faa..cf5db6e 100644 --- a/Source/cmCMakePresetsFile.cxx +++ b/Source/cmCMakePresetsFile.cxx @@ -29,7 +29,8 @@ enum class CycleStatus using ReadFileResult = cmCMakePresetsFile::ReadFileResult; using CacheVariable = cmCMakePresetsFile::CacheVariable; using UnexpandedPreset = cmCMakePresetsFile::UnexpandedPreset; -using CMakeGeneratorConfig = cmCMakePresetsFile::CMakeGeneratorConfig; +using ExpandedPreset = cmCMakePresetsFile::ExpandedPreset; +using ArchToolsetStrategy = cmCMakePresetsFile::ArchToolsetStrategy; constexpr int MIN_VERSION = 1; constexpr int MAX_VERSION = 1; @@ -77,15 +78,37 @@ auto const RootVersionHelper = auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); +ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) +{ + if (!value) { + out.clear(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + out = value->asBool() ? "TRUE" : "FALSE"; + return ReadFileResult::READ_OK; + } + + return VariableStringHelper(out, value); +} + auto const VariableObjectHelper = cmJSONObjectHelper<CacheVariable, ReadFileResult>( ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) - .Bind("value"_s, &CacheVariable::Value, VariableStringHelper); + .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, const Json::Value* value) { + if (value->isBool()) { + out = CacheVariable{ + /*Type=*/"BOOL", + /*Value=*/value->asBool() ? "TRUE" : "FALSE", + }; + return ReadFileResult::READ_OK; + } if (value->isString()) { out = CacheVariable{ /*Type=*/"", @@ -189,8 +212,8 @@ auto const PresetDebugHelper = .Bind("find"_s, &UnexpandedPreset::DebugFind, PresetOptionalBoolHelper, false); -ReadFileResult CMakeGeneratorConfigHelper( - cm::optional<CMakeGeneratorConfig>& out, const Json::Value* value) +ReadFileResult ArchToolsetStrategyHelper( + cm::optional<ArchToolsetStrategy>& out, const Json::Value* value) { if (!value) { out = cm::nullopt; @@ -201,19 +224,56 @@ ReadFileResult CMakeGeneratorConfigHelper( return ReadFileResult::INVALID_PRESET; } - if (value->asString() == "default") { - out = CMakeGeneratorConfig::Default; + if (value->asString() == "set") { + out = ArchToolsetStrategy::Set; return ReadFileResult::READ_OK; } - if (value->asString() == "ignore") { - out = CMakeGeneratorConfig::Ignore; + if (value->asString() == "external") { + out = ArchToolsetStrategy::External; return ReadFileResult::READ_OK; } return ReadFileResult::INVALID_PRESET; } +std::function<ReadFileResult(UnexpandedPreset&, const Json::Value*)> +ArchToolsetHelper( + std::string UnexpandedPreset::*valueField, + cm::optional<ArchToolsetStrategy> UnexpandedPreset::*strategyField) +{ + auto const objectHelper = + cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("value", valueField, PresetStringHelper, false) + .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); + return [valueField, strategyField, objectHelper]( + UnexpandedPreset& out, const Json::Value* value) -> ReadFileResult { + if (!value) { + (out.*valueField).clear(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.*valueField = value->asString(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return objectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; + }; +} + +auto const ArchitectureHelper = ArchToolsetHelper( + &UnexpandedPreset::Architecture, &UnexpandedPreset::ArchitectureStrategy); +auto const ToolsetHelper = ArchToolsetHelper( + &UnexpandedPreset::Toolset, &UnexpandedPreset::ToolsetStrategy); + auto const PresetHelper = cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) @@ -229,11 +289,8 @@ auto const PresetHelper = false) .Bind("generator"_s, &UnexpandedPreset::Generator, PresetStringHelper, false) - .Bind("architecture"_s, &UnexpandedPreset::Architecture, - PresetStringHelper, false) - .Bind("toolset"_s, &UnexpandedPreset::Toolset, PresetStringHelper, false) - .Bind("cmakeGeneratorConfig"_s, &UnexpandedPreset::GeneratorConfig, - CMakeGeneratorConfigHelper, false) + .Bind("architecture"_s, ArchitectureHelper, false) + .Bind("toolset"_s, ToolsetHelper, false) .Bind("binaryDir"_s, &UnexpandedPreset::BinaryDir, PresetStringHelper, false) .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false) @@ -290,9 +347,9 @@ void InheritOptionalBool(cm::optional<bool>& child, * that each preset has the required fields, either directly or through * inheritance. */ -ReadFileResult VisitPreset(std::map<std::string, UnexpandedPreset>& presets, - UnexpandedPreset& preset, - std::map<std::string, CycleStatus> cycleStatus) +ReadFileResult VisitPreset( + std::map<std::string, cmCMakePresetsFile::PresetPair>& presets, + UnexpandedPreset& preset, std::map<std::string, CycleStatus> cycleStatus) { switch (cycleStatus[preset.Name]) { case CycleStatus::InProgress: @@ -318,35 +375,42 @@ ReadFileResult VisitPreset(std::map<std::string, UnexpandedPreset>& presets, return ReadFileResult::INVALID_PRESET; } - if (!preset.User && parent->second.User) { + if (!preset.User && parent->second.Unexpanded.User) { return ReadFileResult::USER_PRESET_INHERITANCE; } - auto result = VisitPreset(presets, parent->second, cycleStatus); + auto result = VisitPreset(presets, parent->second.Unexpanded, cycleStatus); if (result != ReadFileResult::READ_OK) { return result; } - InheritString(preset.Generator, parent->second.Generator); - InheritString(preset.Architecture, parent->second.Architecture); - InheritString(preset.Toolset, parent->second.Toolset); - if (!preset.GeneratorConfig) { - preset.GeneratorConfig = parent->second.GeneratorConfig; + InheritString(preset.Generator, parent->second.Unexpanded.Generator); + InheritString(preset.Architecture, parent->second.Unexpanded.Architecture); + InheritString(preset.Toolset, parent->second.Unexpanded.Toolset); + if (!preset.ArchitectureStrategy) { + preset.ArchitectureStrategy = + parent->second.Unexpanded.ArchitectureStrategy; + } + if (!preset.ToolsetStrategy) { + preset.ToolsetStrategy = parent->second.Unexpanded.ToolsetStrategy; } - InheritString(preset.BinaryDir, parent->second.BinaryDir); - InheritOptionalBool(preset.WarnDev, parent->second.WarnDev); - InheritOptionalBool(preset.ErrorDev, parent->second.ErrorDev); - InheritOptionalBool(preset.WarnDeprecated, parent->second.WarnDeprecated); + InheritString(preset.BinaryDir, parent->second.Unexpanded.BinaryDir); + InheritOptionalBool(preset.WarnDev, parent->second.Unexpanded.WarnDev); + InheritOptionalBool(preset.ErrorDev, parent->second.Unexpanded.ErrorDev); + InheritOptionalBool(preset.WarnDeprecated, + parent->second.Unexpanded.WarnDeprecated); InheritOptionalBool(preset.ErrorDeprecated, - parent->second.ErrorDeprecated); + parent->second.Unexpanded.ErrorDeprecated); InheritOptionalBool(preset.WarnUninitialized, - parent->second.WarnUninitialized); - InheritOptionalBool(preset.WarnUnusedCli, parent->second.WarnUnusedCli); - InheritOptionalBool(preset.WarnSystemVars, parent->second.WarnSystemVars); - for (auto const& v : parent->second.CacheVariables) { + parent->second.Unexpanded.WarnUninitialized); + InheritOptionalBool(preset.WarnUnusedCli, + parent->second.Unexpanded.WarnUnusedCli); + InheritOptionalBool(preset.WarnSystemVars, + parent->second.Unexpanded.WarnSystemVars); + for (auto const& v : parent->second.Unexpanded.CacheVariables) { preset.CacheVariables.insert(v); } - for (auto const& v : parent->second.Environment) { + for (auto const& v : parent->second.Unexpanded.Environment) { preset.Environment.insert(v); } } @@ -371,7 +435,7 @@ ReadFileResult VisitPreset(std::map<std::string, UnexpandedPreset>& presets, } ReadFileResult ComputePresetInheritance( - std::map<std::string, UnexpandedPreset>& presets) + std::map<std::string, cmCMakePresetsFile::PresetPair>& presets) { std::map<std::string, CycleStatus> cycleStatus; for (auto const& it : presets) { @@ -379,7 +443,7 @@ ReadFileResult ComputePresetInheritance( } for (auto& it : presets) { - auto result = VisitPreset(presets, it.second, cycleStatus); + auto result = VisitPreset(presets, it.second.Unexpanded, cycleStatus); if (result != ReadFileResult::READ_OK) { return result; } @@ -415,44 +479,111 @@ bool IsValidMacroNamespace(const std::string& str) return false; } -bool VisitEnv(const cmCMakePresetsFile& file, - cmCMakePresetsFile::ExpandedPreset& preset, - std::map<std::string, CycleStatus>& envCycles, - std::string& value, CycleStatus& status); +enum class ExpandMacroResult +{ + Ok, + Ignore, + Error, +}; + +ExpandMacroResult VisitEnv(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& value, CycleStatus& status); +ExpandMacroResult ExpandMacros(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out); +ExpandMacroResult ExpandMacro(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out, + const std::string& macroNamespace, + const std::string& macroName); + bool ExpandMacros(const cmCMakePresetsFile& file, - cmCMakePresetsFile::ExpandedPreset& preset, - std::map<std::string, CycleStatus>& envCycles, - std::string& out); -bool ExpandMacro(const cmCMakePresetsFile& file, - cmCMakePresetsFile::ExpandedPreset& preset, - std::map<std::string, CycleStatus>& envCycles, - std::string& out, const std::string& macroNamespace, - const std::string& macroName); - -bool VisitEnv(const cmCMakePresetsFile& file, - cmCMakePresetsFile::ExpandedPreset& preset, - std::map<std::string, CycleStatus>& envCycles, - std::string& value, CycleStatus& status) + const UnexpandedPreset& preset, + cm::optional<ExpandedPreset>& out) +{ + out = preset; + + std::map<std::string, CycleStatus> envCycles; + for (auto const& v : out->Environment) { + envCycles[v.first] = CycleStatus::Unvisited; + } + + for (auto& v : out->Environment) { + if (v.second) { + switch (VisitEnv(file, *out, envCycles, *v.second, envCycles[v.first])) { + case ExpandMacroResult::Error: + return false; + case ExpandMacroResult::Ignore: + out.reset(); + return true; + case ExpandMacroResult::Ok: + break; + } + } + } + + std::string binaryDir = preset.BinaryDir; + switch (ExpandMacros(file, *out, envCycles, binaryDir)) { + case ExpandMacroResult::Error: + return false; + case ExpandMacroResult::Ignore: + out.reset(); + return true; + case ExpandMacroResult::Ok: + break; + } + if (!cmSystemTools::FileIsFullPath(binaryDir)) { + binaryDir = cmStrCat(file.SourceDir, '/', binaryDir); + } + out->BinaryDir = cmSystemTools::CollapseFullPath(binaryDir); + cmSystemTools::ConvertToUnixSlashes(out->BinaryDir); + + for (auto& variable : out->CacheVariables) { + if (variable.second) { + switch (ExpandMacros(file, *out, envCycles, variable.second->Value)) { + case ExpandMacroResult::Error: + return false; + case ExpandMacroResult::Ignore: + out.reset(); + return true; + case ExpandMacroResult::Ok: + break; + } + } + } + + return true; +} + +ExpandMacroResult VisitEnv(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& value, CycleStatus& status) { if (status == CycleStatus::Verified) { - return true; + return ExpandMacroResult::Ok; } if (status == CycleStatus::InProgress) { - return false; + return ExpandMacroResult::Error; } status = CycleStatus::InProgress; - if (!ExpandMacros(file, preset, envCycles, value)) { - return false; + auto e = ExpandMacros(file, preset, envCycles, value); + if (e != ExpandMacroResult::Ok) { + return e; } status = CycleStatus::Verified; - return true; + return ExpandMacroResult::Ok; } -bool ExpandMacros(const cmCMakePresetsFile& file, - cmCMakePresetsFile::ExpandedPreset& preset, - std::map<std::string, CycleStatus>& envCycles, - std::string& out) +ExpandMacroResult ExpandMacros(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out) { std::string result; std::string macroNamespace; @@ -499,9 +630,10 @@ bool ExpandMacros(const cmCMakePresetsFile& file, case State::MacroName: if (c == '}') { - if (!ExpandMacro(file, preset, envCycles, result, macroNamespace, - macroName)) { - return false; + auto e = ExpandMacro(file, preset, envCycles, result, macroNamespace, + macroName); + if (e != ExpandMacroResult::Ok) { + return e; } macroNamespace.clear(); macroName.clear(); @@ -521,67 +653,76 @@ bool ExpandMacros(const cmCMakePresetsFile& file, result += macroNamespace; break; case State::MacroName: - return false; + return ExpandMacroResult::Error; } out = std::move(result); - return true; + return ExpandMacroResult::Ok; } -bool ExpandMacro(const cmCMakePresetsFile& file, - cmCMakePresetsFile::ExpandedPreset& preset, - std::map<std::string, CycleStatus>& envCycles, - std::string& out, const std::string& macroNamespace, - const std::string& macroName) +ExpandMacroResult ExpandMacro(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out, + const std::string& macroNamespace, + const std::string& macroName) { if (macroNamespace.empty()) { if (macroName == "sourceDir") { out += file.SourceDir; - return true; + return ExpandMacroResult::Ok; } if (macroName == "sourceParentDir") { out += cmSystemTools::GetParentDirectory(file.SourceDir); - return true; + return ExpandMacroResult::Ok; + } + if (macroName == "sourceDirName") { + out += cmSystemTools::GetFilenameName(file.SourceDir); + return ExpandMacroResult::Ok; } if (macroName == "presetName") { out += preset.Name; - return true; + return ExpandMacroResult::Ok; } if (macroName == "generator") { out += preset.Generator; - return true; + return ExpandMacroResult::Ok; } if (macroName == "dollar") { out += '$'; - return true; + return ExpandMacroResult::Ok; } } if (macroNamespace == "env" && !macroName.empty()) { auto v = preset.Environment.find(macroName); if (v != preset.Environment.end() && v->second) { - if (!VisitEnv(file, preset, envCycles, *v->second, - envCycles[macroName])) { - return false; + auto e = + VisitEnv(file, preset, envCycles, *v->second, envCycles[macroName]); + if (e != ExpandMacroResult::Ok) { + return e; } out += *v->second; - return true; + return ExpandMacroResult::Ok; } } if (macroNamespace == "env" || macroNamespace == "penv") { if (macroName.empty()) { - return false; + return ExpandMacroResult::Error; } const char* value = std::getenv(macroName.c_str()); if (value) { out += value; } - return true; + return ExpandMacroResult::Ok; } - // "vendor" falls through to here - return false; + if (macroNamespace == "vendor") { + return ExpandMacroResult::Ignore; + } + + return ExpandMacroResult::Error; } } @@ -604,7 +745,7 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( this->PresetOrder.clear(); std::vector<std::string> presetOrder; - std::map<std::string, UnexpandedPreset> presetMap; + std::map<std::string, PresetPair> presetMap; std::string filename = GetUserFilename(this->SourceDir); if (cmSystemTools::FileExists(filename)) { @@ -634,6 +775,12 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( return result; } + for (auto& it : presetMap) { + if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) { + return ReadFileResult::INVALID_MACRO_EXPANSION; + } + } + this->PresetOrder = std::move(presetOrder); this->Presets = std::move(presetMap); return ReadFileResult::READ_OK; @@ -672,51 +819,16 @@ const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) return "Cyclic preset inheritance"; case ReadFileResult::USER_PRESET_INHERITANCE: return "Project preset inherits from user preset"; - default: - return "Unknown error"; - } -} - -cm::optional<cmCMakePresetsFile::ExpandedPreset> -cmCMakePresetsFile::ExpandMacros(const UnexpandedPreset& preset) const -{ - ExpandedPreset retval{ preset }; - - std::map<std::string, CycleStatus> envCycles; - for (auto const& v : retval.Environment) { - envCycles[v.first] = CycleStatus::Unvisited; - } - - for (auto& v : retval.Environment) { - if (v.second && - !VisitEnv(*this, retval, envCycles, *v.second, envCycles[v.first])) { - return cm::nullopt; - } - } - - std::string binaryDir = preset.BinaryDir; - if (!::ExpandMacros(*this, retval, envCycles, binaryDir)) { - return cm::nullopt; - } - if (!cmSystemTools::FileIsFullPath(binaryDir)) { - binaryDir = cmStrCat(this->SourceDir, '/', binaryDir); - } - retval.BinaryDir = cmSystemTools::CollapseFullPath(binaryDir); - cmSystemTools::ConvertToUnixSlashes(retval.BinaryDir); - - for (auto& variable : retval.CacheVariables) { - if (variable.second && - !::ExpandMacros(*this, retval, envCycles, variable.second->Value)) { - return cm::nullopt; - } + case ReadFileResult::INVALID_MACRO_EXPANSION: + return "Invalid macro expansion"; } - return cm::make_optional(retval); + return "Unknown error"; } cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( const std::string& filename, std::vector<std::string>& presetOrder, - std::map<std::string, UnexpandedPreset>& presetMap, bool user) + std::map<std::string, PresetPair>& presetMap, bool user) { cmsys::ifstream fin(filename.c_str()); if (!fin) { @@ -763,7 +875,7 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( if (preset.Name.empty()) { return ReadFileResult::INVALID_PRESET; } - if (!presetMap.insert({ preset.Name, preset }).second) { + if (!presetMap.insert({ preset.Name, { preset, cm::nullopt } }).second) { return ReadFileResult::DUPLICATE_PRESETS; } presetOrder.push_back(preset.Name); diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsFile.h index 70ec4c5..f6b159a 100644 --- a/Source/cmCMakePresetsFile.h +++ b/Source/cmCMakePresetsFile.h @@ -12,10 +12,10 @@ class cmCMakePresetsFile { public: - enum class CMakeGeneratorConfig + enum class ArchToolsetStrategy { - Default, - Ignore, + Set, + External, }; class CacheVariable @@ -50,8 +50,9 @@ public: std::string Description; std::string Generator; std::string Architecture; + cm::optional<ArchToolsetStrategy> ArchitectureStrategy; std::string Toolset; - cm::optional<CMakeGeneratorConfig> GeneratorConfig; + cm::optional<ArchToolsetStrategy> ToolsetStrategy; std::string BinaryDir; std::map<std::string, cm::optional<CacheVariable>> CacheVariables; @@ -102,8 +103,15 @@ public: } }; + class PresetPair + { + public: + UnexpandedPreset Unexpanded; + cm::optional<ExpandedPreset> Expanded; + }; + std::string SourceDir; - std::map<std::string, UnexpandedPreset> Presets; + std::map<std::string, PresetPair> Presets; std::vector<std::string> PresetOrder; enum class ReadFileResult @@ -123,6 +131,7 @@ public: DUPLICATE_PRESETS, CYCLIC_PRESET_INHERITANCE, USER_PRESET_INHERITANCE, + INVALID_MACRO_EXPANSION, }; static std::string GetFilename(const std::string& sourceDir); @@ -131,11 +140,9 @@ public: bool allowNoFiles = false); static const char* ResultToString(ReadFileResult result); - cm::optional<ExpandedPreset> ExpandMacros( - const UnexpandedPreset& preset) const; - private: - ReadFileResult ReadJSONFile( - const std::string& filename, std::vector<std::string>& presetOrder, - std::map<std::string, UnexpandedPreset>& presetMap, bool user); + ReadFileResult ReadJSONFile(const std::string& filename, + std::vector<std::string>& presetOrder, + std::map<std::string, PresetPair>& presetMap, + bool user); }; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2a14b03..291ce22 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1042,17 +1042,17 @@ void cmake::SetArgs(const std::vector<std::string>& args) this->PrintPresetList(settingsFile); return; } - if (preset->second.Hidden) { + if (preset->second.Unexpanded.Hidden) { cmSystemTools::Error(cmStrCat("Cannot use hidden preset in ", this->GetHomeDirectory(), ": \"", presetName, '"')); this->PrintPresetList(settingsFile); return; } - auto expandedPreset = settingsFile.ExpandMacros(preset->second); + auto const& expandedPreset = preset->second.Expanded; if (!expandedPreset) { cmSystemTools::Error(cmStrCat("Could not evaluate preset \"", - preset->second.Name, + preset->second.Unexpanded.Name, "\": Invalid macro expansion")); return; } @@ -1069,12 +1069,16 @@ void cmake::SetArgs(const std::vector<std::string>& args) this->UnprocessedPresetVariables = expandedPreset->CacheVariables; this->UnprocessedPresetEnvironment = expandedPreset->Environment; - if (!expandedPreset->GeneratorConfig || - expandedPreset->GeneratorConfig == - cmCMakePresetsFile::CMakeGeneratorConfig::Default) { + if (!expandedPreset->ArchitectureStrategy || + expandedPreset->ArchitectureStrategy == + cmCMakePresetsFile::ArchToolsetStrategy::Set) { if (!this->GeneratorPlatformSet) { this->SetGeneratorPlatform(expandedPreset->Architecture); } + } + if (!expandedPreset->ToolsetStrategy || + expandedPreset->ToolsetStrategy == + cmCMakePresetsFile::ArchToolsetStrategy::Set) { if (!this->GeneratorToolsetSet) { this->SetGeneratorToolset(expandedPreset->Toolset); } @@ -1464,13 +1468,12 @@ void cmake::PrintPresetList(const cmCMakePresetsFile& file) const std::vector<cmCMakePresetsFile::UnexpandedPreset> presets; for (auto const& p : file.PresetOrder) { auto const& preset = file.Presets.at(p); - if (!preset.Hidden && + if (!preset.Unexpanded.Hidden && preset.Expanded && std::find_if(generators.begin(), generators.end(), [&preset](const GeneratorInfo& info) { - return info.name == preset.Generator; - }) != generators.end() && - file.ExpandMacros(preset)) { - presets.push_back(preset); + return info.name == preset.Unexpanded.Generator; + }) != generators.end()) { + presets.push_back(preset.Unexpanded); } } |