summaryrefslogtreecommitdiffstats
path: root/Source/QtDialog/QCMake.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/QtDialog/QCMake.cxx')
-rw-r--r--Source/QtDialog/QCMake.cxx481
1 files changed, 481 insertions, 0 deletions
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
new file mode 100644
index 0000000..7e94a27
--- /dev/null
+++ b/Source/QtDialog/QCMake.cxx
@@ -0,0 +1,481 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "QCMake.h"
+
+#include <QCoreApplication>
+#include <QDir>
+
+#include "cmExternalMakefileProjectGenerator.h"
+#include "cmState.h"
+#include "cmSystemTools.h"
+
+#ifdef Q_OS_WIN
+#include "qt_windows.h" // For SetErrorMode
+#endif
+
+QCMake::QCMake(QObject* p)
+ : QObject(p)
+{
+ this->WarnUninitializedMode = false;
+ this->WarnUnusedMode = false;
+ qRegisterMetaType<QCMakeProperty>();
+ qRegisterMetaType<QCMakePropertyList>();
+
+ cmSystemTools::DisableRunCommandOutput();
+ cmSystemTools::SetRunCommandHideConsole(true);
+ cmSystemTools::SetMessageCallback(QCMake::messageCallback, this);
+ cmSystemTools::SetStdoutCallback(QCMake::stdoutCallback, this);
+ cmSystemTools::SetStderrCallback(QCMake::stderrCallback, this);
+
+ this->CMakeInstance = new cmake(cmake::RoleProject);
+ this->CMakeInstance->SetCMakeEditCommand(
+ cmSystemTools::GetCMakeGUICommand());
+ this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
+
+ cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
+
+ std::vector<cmake::GeneratorInfo> generators;
+ this->CMakeInstance->GetRegisteredGenerators(generators);
+
+ std::vector<cmake::GeneratorInfo>::const_iterator it;
+ for (it = generators.begin(); it != generators.end(); ++it) {
+ // Skip the generator "KDevelop3", since there is also
+ // "KDevelop3 - Unix Makefiles", which is the full and official name.
+ // The short name is actually only still there since this was the name
+ // in CMake 2.4, to keep "command line argument compatibility", but
+ // this is not necessary in the GUI.
+ if (it->name == "KDevelop3") {
+ continue;
+ }
+
+ this->AvailableGenerators.push_back(*it);
+ }
+}
+
+QCMake::~QCMake()
+{
+ delete this->CMakeInstance;
+ // cmDynamicLoader::FlushCache();
+}
+
+void QCMake::loadCache(const QString& dir)
+{
+ this->setBinaryDirectory(dir);
+}
+
+void QCMake::setSourceDirectory(const QString& _dir)
+{
+ QString dir = QString::fromLocal8Bit(
+ cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str());
+ if (this->SourceDirectory != dir) {
+ this->SourceDirectory = QDir::fromNativeSeparators(dir);
+ emit this->sourceDirChanged(this->SourceDirectory);
+ }
+}
+
+void QCMake::setBinaryDirectory(const QString& _dir)
+{
+ QString dir = QString::fromLocal8Bit(
+ cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str());
+ if (this->BinaryDirectory != dir) {
+ this->BinaryDirectory = QDir::fromNativeSeparators(dir);
+ emit this->binaryDirChanged(this->BinaryDirectory);
+ cmState* state = this->CMakeInstance->GetState();
+ this->setGenerator(QString());
+ this->setToolset(QString());
+ if (!this->CMakeInstance->LoadCache(
+ this->BinaryDirectory.toLocal8Bit().data())) {
+ QDir testDir(this->BinaryDirectory);
+ if (testDir.exists("CMakeCache.txt")) {
+ cmSystemTools::Error(
+ "There is a CMakeCache.txt file for the current binary "
+ "tree but cmake does not have permission to read it. "
+ "Please check the permissions of the directory you are trying to "
+ "run CMake on.");
+ }
+ }
+
+ QCMakePropertyList props = this->properties();
+ emit this->propertiesChanged(props);
+ const char* homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
+ if (homeDir) {
+ setSourceDirectory(QString::fromLocal8Bit(homeDir));
+ }
+ const char* gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
+ if (gen) {
+ const char* extraGen =
+ state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
+ std::string curGen =
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+ gen, extraGen ? extraGen : "");
+ this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
+ }
+
+ const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ if (toolset) {
+ this->setToolset(QString::fromLocal8Bit(toolset));
+ }
+
+ checkOpenPossible();
+ }
+}
+
+void QCMake::setGenerator(const QString& gen)
+{
+ if (this->Generator != gen) {
+ this->Generator = gen;
+ emit this->generatorChanged(this->Generator);
+ }
+}
+
+void QCMake::setToolset(const QString& toolset)
+{
+ if (this->Toolset != toolset) {
+ this->Toolset = toolset;
+ emit this->toolsetChanged(this->Toolset);
+ }
+}
+
+void QCMake::configure()
+{
+#ifdef Q_OS_WIN
+ 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->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();
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->propertiesChanged(this->properties());
+ emit this->configureDone(err);
+}
+
+void QCMake::generate()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#endif
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ int err = this->CMakeInstance->Generate();
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->generateDone(err);
+ checkOpenPossible();
+}
+
+void QCMake::open()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#endif
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ auto successful = this->CMakeInstance->Open(
+ this->BinaryDirectory.toLocal8Bit().data(), false);
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->openDone(successful);
+}
+
+void QCMake::setProperties(const QCMakePropertyList& newProps)
+{
+ QCMakePropertyList props = newProps;
+
+ QStringList toremove;
+
+ // set the value of properties
+ cmState* state = this->CMakeInstance->GetState();
+ std::vector<std::string> cacheKeys = state->GetCacheEntryKeys();
+ for (std::vector<std::string>::const_iterator it = cacheKeys.begin();
+ it != cacheKeys.end(); ++it) {
+ cmStateEnums::CacheEntryType t = state->GetCacheEntryType(*it);
+ if (t == cmStateEnums::INTERNAL || t == cmStateEnums::STATIC) {
+ continue;
+ }
+
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(it->c_str());
+ int idx = props.indexOf(prop);
+ if (idx == -1) {
+ toremove.append(QString::fromLocal8Bit(it->c_str()));
+ } else {
+ prop = props[idx];
+ if (prop.Value.type() == QVariant::Bool) {
+ state->SetCacheEntryValue(*it, prop.Value.toBool() ? "ON" : "OFF");
+ } else {
+ state->SetCacheEntryValue(*it,
+ prop.Value.toString().toLocal8Bit().data());
+ }
+ props.removeAt(idx);
+ }
+ }
+
+ // remove some properites
+ foreach (QString const& s, toremove) {
+ this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data());
+
+ state->RemoveCacheEntry(s.toLocal8Bit().data());
+ }
+
+ // add some new properites
+ foreach (QCMakeProperty const& s, props) {
+ this->CMakeInstance->WatchUnusedCli(s.Key.toLocal8Bit().data());
+
+ if (s.Type == QCMakeProperty::BOOL) {
+ this->CMakeInstance->AddCacheEntry(
+ s.Key.toLocal8Bit().data(), s.Value.toBool() ? "ON" : "OFF",
+ s.Help.toLocal8Bit().data(), cmStateEnums::BOOL);
+ } else if (s.Type == QCMakeProperty::STRING) {
+ this->CMakeInstance->AddCacheEntry(
+ s.Key.toLocal8Bit().data(), s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(), cmStateEnums::STRING);
+ } else if (s.Type == QCMakeProperty::PATH) {
+ this->CMakeInstance->AddCacheEntry(
+ s.Key.toLocal8Bit().data(), s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(), cmStateEnums::PATH);
+ } else if (s.Type == QCMakeProperty::FILEPATH) {
+ this->CMakeInstance->AddCacheEntry(
+ s.Key.toLocal8Bit().data(), s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(), cmStateEnums::FILEPATH);
+ }
+ }
+
+ this->CMakeInstance->SaveCache(this->BinaryDirectory.toLocal8Bit().data());
+}
+
+QCMakePropertyList QCMake::properties() const
+{
+ QCMakePropertyList ret;
+
+ cmState* state = this->CMakeInstance->GetState();
+ std::vector<std::string> cacheKeys = state->GetCacheEntryKeys();
+ for (std::vector<std::string>::const_iterator i = cacheKeys.begin();
+ i != cacheKeys.end(); ++i) {
+ cmStateEnums::CacheEntryType t = state->GetCacheEntryType(*i);
+ if (t == cmStateEnums::INTERNAL || t == cmStateEnums::STATIC ||
+ t == cmStateEnums::UNINITIALIZED) {
+ continue;
+ }
+
+ const char* cachedValue = state->GetCacheEntryValue(*i);
+
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(i->c_str());
+ prop.Help =
+ QString::fromLocal8Bit(state->GetCacheEntryProperty(*i, "HELPSTRING"));
+ prop.Value = QString::fromLocal8Bit(cachedValue);
+ prop.Advanced = state->GetCacheEntryPropertyAsBool(*i, "ADVANCED");
+ if (t == cmStateEnums::BOOL) {
+ prop.Type = QCMakeProperty::BOOL;
+ prop.Value = cmSystemTools::IsOn(cachedValue);
+ } else if (t == cmStateEnums::PATH) {
+ prop.Type = QCMakeProperty::PATH;
+ } else if (t == cmStateEnums::FILEPATH) {
+ prop.Type = QCMakeProperty::FILEPATH;
+ } else if (t == cmStateEnums::STRING) {
+ prop.Type = QCMakeProperty::STRING;
+ const char* stringsProperty =
+ state->GetCacheEntryProperty(*i, "STRINGS");
+ if (stringsProperty) {
+ prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";");
+ }
+ }
+
+ ret.append(prop);
+ }
+
+ return ret;
+}
+
+void QCMake::interrupt()
+{
+ this->InterruptFlag.ref();
+}
+
+bool QCMake::interruptCallback(void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ return self->InterruptFlag;
+#else
+ return self->InterruptFlag.load();
+#endif
+}
+
+void QCMake::progressCallback(const char* msg, float percent, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ if (percent >= 0) {
+ emit self->progressChanged(QString::fromLocal8Bit(msg), percent);
+ } else {
+ emit self->outputMessage(QString::fromLocal8Bit(msg));
+ }
+ QCoreApplication::processEvents();
+}
+
+void QCMake::messageCallback(const char* msg, const char* /*title*/,
+ bool& /*stop*/, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->errorMessage(QString::fromLocal8Bit(msg));
+ QCoreApplication::processEvents();
+}
+
+void QCMake::stdoutCallback(const char* msg, size_t len, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->outputMessage(QString::fromLocal8Bit(msg, int(len)));
+ QCoreApplication::processEvents();
+}
+
+void QCMake::stderrCallback(const char* msg, size_t len, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->outputMessage(QString::fromLocal8Bit(msg, int(len)));
+ QCoreApplication::processEvents();
+}
+
+QString QCMake::binaryDirectory() const
+{
+ return this->BinaryDirectory;
+}
+
+QString QCMake::sourceDirectory() const
+{
+ return this->SourceDirectory;
+}
+
+QString QCMake::generator() const
+{
+ return this->Generator;
+}
+
+std::vector<cmake::GeneratorInfo> const& QCMake::availableGenerators() const
+{
+ return AvailableGenerators;
+}
+
+void QCMake::deleteCache()
+{
+ // delete cache
+ this->CMakeInstance->DeleteCache(this->BinaryDirectory.toLocal8Bit().data());
+ // reload to make our cache empty
+ this->CMakeInstance->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ // emit no generator and no properties
+ this->setGenerator(QString());
+ this->setToolset(QString());
+ QCMakePropertyList props = this->properties();
+ emit this->propertiesChanged(props);
+}
+
+void QCMake::reloadCache()
+{
+ // emit that the cache was cleaned out
+ QCMakePropertyList props;
+ emit this->propertiesChanged(props);
+ // reload
+ this->CMakeInstance->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ // emit new cache properties
+ props = this->properties();
+ emit this->propertiesChanged(props);
+}
+
+void QCMake::setDebugOutput(bool flag)
+{
+ if (flag != this->CMakeInstance->GetDebugOutput()) {
+ this->CMakeInstance->SetDebugOutputOn(flag);
+ emit this->debugOutputChanged(flag);
+ }
+}
+
+bool QCMake::getDebugOutput() const
+{
+ return this->CMakeInstance->GetDebugOutput();
+}
+
+bool QCMake::getSuppressDevWarnings()
+{
+ return this->CMakeInstance->GetSuppressDevWarnings();
+}
+
+void QCMake::setSuppressDevWarnings(bool value)
+{
+ this->CMakeInstance->SetSuppressDevWarnings(value);
+}
+
+bool QCMake::getSuppressDeprecatedWarnings()
+{
+ return this->CMakeInstance->GetSuppressDeprecatedWarnings();
+}
+
+void QCMake::setSuppressDeprecatedWarnings(bool value)
+{
+ this->CMakeInstance->SetSuppressDeprecatedWarnings(value);
+}
+
+bool QCMake::getDevWarningsAsErrors()
+{
+ return this->CMakeInstance->GetDevWarningsAsErrors();
+}
+
+void QCMake::setDevWarningsAsErrors(bool value)
+{
+ this->CMakeInstance->SetDevWarningsAsErrors(value);
+}
+
+bool QCMake::getDeprecatedWarningsAsErrors()
+{
+ return this->CMakeInstance->GetDeprecatedWarningsAsErrors();
+}
+
+void QCMake::setDeprecatedWarningsAsErrors(bool value)
+{
+ this->CMakeInstance->SetDeprecatedWarningsAsErrors(value);
+}
+
+void QCMake::setWarnUninitializedMode(bool value)
+{
+ this->WarnUninitializedMode = value;
+}
+
+void QCMake::setWarnUnusedMode(bool value)
+{
+ this->WarnUnusedMode = value;
+}
+
+void QCMake::checkOpenPossible()
+{
+ auto data = this->BinaryDirectory.toLocal8Bit().data();
+ auto possible = this->CMakeInstance->Open(data, true);
+ emit openPossible(possible);
+}