summaryrefslogtreecommitdiff
path: root/Source/QtDialog/QCMake.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/QtDialog/QCMake.cxx')
-rw-r--r--Source/QtDialog/QCMake.cxx262
1 files changed, 227 insertions, 35 deletions
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 776af81ff..2f41f70bf 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -2,10 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "QCMake.h"
+#include <algorithm>
+
#include <cm/memory>
#include <QCoreApplication>
#include <QDir>
+#include <QString>
+#include <QVector>
#include "cmExternalMakefileProjectGenerator.h"
#include "cmGlobalGenerator.h"
@@ -19,11 +23,15 @@
QCMake::QCMake(QObject* p)
: QObject(p)
+ , StartEnvironment(QProcessEnvironment::systemEnvironment())
+ , Environment(QProcessEnvironment::systemEnvironment())
{
this->WarnUninitializedMode = false;
- this->WarnUnusedMode = false;
qRegisterMetaType<QCMakeProperty>();
qRegisterMetaType<QCMakePropertyList>();
+ qRegisterMetaType<QProcessEnvironment>();
+ qRegisterMetaType<QVector<QCMakePreset>>();
+ qRegisterMetaType<cmCMakePresetsFile::ReadFileResult>();
cmSystemTools::DisableRunCommandOutput();
cmSystemTools::SetRunCommandHideConsole(true);
@@ -56,6 +64,17 @@ QCMake::QCMake(QObject* p)
for (cmake::GeneratorInfo const& gen : generators) {
this->AvailableGenerators.push_back(gen);
}
+
+ connect(&this->LoadPresetsTimer, &QTimer::timeout, this, [this]() {
+ this->loadPresets();
+ if (!this->PresetName.isEmpty() &&
+ this->CMakePresetsFile.Presets.find(
+ std::string(this->PresetName.toLocal8Bit())) ==
+ this->CMakePresetsFile.Presets.end()) {
+ this->setPreset(QString{});
+ }
+ });
+ this->LoadPresetsTimer.start(1000);
}
QCMake::~QCMake() = default;
@@ -72,6 +91,8 @@ void QCMake::setSourceDirectory(const QString& _dir)
if (this->SourceDirectory != dir) {
this->SourceDirectory = QDir::fromNativeSeparators(dir);
emit this->sourceDirChanged(this->SourceDirectory);
+ this->loadPresets();
+ this->setPreset(QString{});
}
}
@@ -128,6 +149,56 @@ void QCMake::setBinaryDirectory(const QString& _dir)
}
}
+void QCMake::setPreset(const QString& name, bool setBinary)
+{
+ if (this->PresetName != name) {
+ this->PresetName = name;
+ emit this->presetChanged(this->PresetName);
+
+ if (!name.isNull()) {
+ std::string presetName(name.toLocal8Bit());
+ auto const& expandedPreset =
+ this->CMakePresetsFile.Presets[presetName].Expanded;
+ if (expandedPreset) {
+ if (setBinary) {
+ QString binaryDir =
+ QString::fromLocal8Bit(expandedPreset->BinaryDir.data());
+ this->setBinaryDirectory(binaryDir);
+ }
+ if (expandedPreset->WarnDev) {
+ this->CMakeInstance->SetSuppressDevWarnings(
+ !*expandedPreset->WarnDev);
+ }
+ if (expandedPreset->ErrorDev) {
+ this->CMakeInstance->SetDevWarningsAsErrors(
+ *expandedPreset->ErrorDev);
+ }
+ if (expandedPreset->WarnDeprecated) {
+ this->CMakeInstance->SetSuppressDeprecatedWarnings(
+ !*expandedPreset->WarnDeprecated);
+ }
+ if (expandedPreset->ErrorDeprecated) {
+ this->CMakeInstance->SetDeprecatedWarningsAsErrors(
+ *expandedPreset->ErrorDeprecated);
+ }
+ if (expandedPreset->WarnUninitialized) {
+ this->WarnUninitializedMode = *expandedPreset->WarnUninitialized;
+ emit this->warnUninitializedModeChanged(
+ *expandedPreset->WarnUninitialized);
+ }
+ this->Environment = this->StartEnvironment;
+ for (auto const& v : expandedPreset->Environment) {
+ if (v.second) {
+ this->Environment.insert(QString::fromLocal8Bit(v.first.data()),
+ QString::fromLocal8Bit(v.second->data()));
+ }
+ }
+ }
+ }
+ emit this->propertiesChanged(this->properties());
+ }
+}
+
void QCMake::setGenerator(const QString& gen)
{
if (this->Generator != gen) {
@@ -152,35 +223,46 @@ void QCMake::setToolset(const QString& toolset)
}
}
+void QCMake::setEnvironment(const QProcessEnvironment& environment)
+{
+ this->Environment = environment;
+}
+
void QCMake::configure()
{
+ int err;
+ {
+ cmSystemTools::SaveRestoreEnvironment restoreEnv;
+ this->setUpEnvironment();
+
#ifdef Q_OS_WIN
- UINT lastErrorMode = SetErrorMode(0);
+ UINT lastErrorMode = SetErrorMode(0);
#endif
- this->CMakeInstance->SetHomeDirectory(
- this->SourceDirectory.toLocal8Bit().data());
- this->CMakeInstance->SetHomeOutputDirectory(
- this->BinaryDirectory.toLocal8Bit().data());
- this->CMakeInstance->SetGlobalGenerator(
- this->CMakeInstance->CreateGlobalGenerator(
- this->Generator.toLocal8Bit().data()));
- this->CMakeInstance->SetGeneratorPlatform(
- this->Platform.toLocal8Bit().data());
- this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
- this->CMakeInstance->LoadCache();
- this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
- this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
- this->CMakeInstance->PreLoadCMakeFiles();
-
- InterruptFlag = 0;
- cmSystemTools::ResetErrorOccuredFlag();
-
- int err = this->CMakeInstance->Configure();
+ this->CMakeInstance->SetHomeDirectory(
+ this->SourceDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SetHomeOutputDirectory(
+ this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SetGlobalGenerator(
+ this->CMakeInstance->CreateGlobalGenerator(
+ this->Generator.toLocal8Bit().data()));
+ this->CMakeInstance->SetGeneratorPlatform(
+ this->Platform.toLocal8Bit().data());
+ this->CMakeInstance->SetGeneratorToolset(
+ this->Toolset.toLocal8Bit().data());
+ this->CMakeInstance->LoadCache();
+ this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
+ this->CMakeInstance->PreLoadCMakeFiles();
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ err = this->CMakeInstance->Configure();
#ifdef Q_OS_WIN
- SetErrorMode(lastErrorMode);
+ SetErrorMode(lastErrorMode);
#endif
+ }
emit this->propertiesChanged(this->properties());
emit this->configureDone(err);
@@ -188,18 +270,24 @@ void QCMake::configure()
void QCMake::generate()
{
+ int err;
+ {
+ cmSystemTools::SaveRestoreEnvironment restoreEnv;
+ this->setUpEnvironment();
+
#ifdef Q_OS_WIN
- UINT lastErrorMode = SetErrorMode(0);
+ UINT lastErrorMode = SetErrorMode(0);
#endif
- InterruptFlag = 0;
- cmSystemTools::ResetErrorOccuredFlag();
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
- int err = this->CMakeInstance->Generate();
+ err = this->CMakeInstance->Generate();
#ifdef Q_OS_WIN
- SetErrorMode(lastErrorMode);
+ SetErrorMode(lastErrorMode);
#endif
+ }
emit this->generateDone(err);
checkOpenPossible();
@@ -330,6 +418,55 @@ QCMakePropertyList QCMake::properties() const
ret.append(prop);
}
+ if (!this->PresetName.isNull()) {
+ std::string presetName(this->PresetName.toLocal8Bit());
+ auto const& p = this->CMakePresetsFile.Presets.at(presetName).Expanded;
+ if (p) {
+ for (auto const& v : p->CacheVariables) {
+ if (!v.second) {
+ continue;
+ }
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(v.first.data());
+ prop.Value = QString::fromLocal8Bit(v.second->Value.data());
+ prop.Type = QCMakeProperty::STRING;
+ if (!v.second->Type.empty()) {
+ auto type = cmState::StringToCacheEntryType(v.second->Type);
+ switch (type) {
+ case cmStateEnums::BOOL:
+ prop.Type = QCMakeProperty::BOOL;
+ prop.Value = cmIsOn(v.second->Value);
+ break;
+ case cmStateEnums::PATH:
+ prop.Type = QCMakeProperty::PATH;
+ break;
+ case cmStateEnums::FILEPATH:
+ prop.Type = QCMakeProperty::FILEPATH;
+ break;
+ default:
+ prop.Type = QCMakeProperty::STRING;
+ break;
+ }
+ }
+
+ // QCMakeCacheModel prefers variables earlier in the list rather than
+ // later, so overwrite them if they already exist rather than simply
+ // appending
+ bool found = false;
+ for (auto& orig : ret) {
+ if (orig.Key == prop.Key) {
+ orig = prop;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ret.append(prop);
+ }
+ }
+ }
+ }
+
return ret;
}
@@ -340,10 +477,10 @@ void QCMake::interrupt()
bool QCMake::interruptCallback()
{
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
- return this->InterruptFlag;
-#else
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
return this->InterruptFlag.load();
+#else
+ return this->InterruptFlag.loadRelaxed();
#endif
}
@@ -375,6 +512,61 @@ void QCMake::stderrCallback(std::string const& msg)
QCoreApplication::processEvents();
}
+void QCMake::setUpEnvironment() const
+{
+ auto env = QProcessEnvironment::systemEnvironment();
+ for (auto const& key : env.keys()) {
+ cmSystemTools::UnsetEnv(key.toLocal8Bit().data());
+ }
+
+ for (auto const& var : this->Environment.toStringList()) {
+ cmSystemTools::PutEnv(var.toLocal8Bit().data());
+ }
+}
+
+void QCMake::loadPresets()
+{
+ auto result = this->CMakePresetsFile.ReadProjectPresets(
+ this->SourceDirectory.toLocal8Bit().data(), true);
+ if (result != this->LastLoadPresetsResult &&
+ result != cmCMakePresetsFile::ReadFileResult::READ_OK) {
+ emit this->presetLoadError(this->SourceDirectory, result);
+ }
+ this->LastLoadPresetsResult = result;
+
+ QVector<QCMakePreset> presets;
+ for (auto const& name : this->CMakePresetsFile.PresetOrder) {
+ auto const& it = this->CMakePresetsFile.Presets[name];
+ auto const& p = it.Unexpanded;
+ if (p.Hidden) {
+ continue;
+ }
+
+ QCMakePreset preset;
+ preset.name = std::move(QString::fromLocal8Bit(p.Name.data()));
+ preset.displayName =
+ std::move(QString::fromLocal8Bit(p.DisplayName.data()));
+ preset.description =
+ std::move(QString::fromLocal8Bit(p.Description.data()));
+ 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.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);
+}
+
QString QCMake::binaryDirectory() const
{
return this->BinaryDirectory;
@@ -390,6 +582,11 @@ QString QCMake::generator() const
return this->Generator;
}
+QProcessEnvironment QCMake::environment() const
+{
+ return this->Environment;
+}
+
std::vector<cmake::GeneratorInfo> const& QCMake::availableGenerators() const
{
return AvailableGenerators;
@@ -478,11 +675,6 @@ void QCMake::setWarnUninitializedMode(bool value)
this->WarnUninitializedMode = value;
}
-void QCMake::setWarnUnusedMode(bool value)
-{
- this->WarnUnusedMode = value;
-}
-
void QCMake::checkOpenPossible()
{
std::string data = this->BinaryDirectory.toLocal8Bit().data();