diff options
Diffstat (limited to 'Source/QtDialog/QCMake.cxx')
-rw-r--r-- | Source/QtDialog/QCMake.cxx | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx new file mode 100644 index 0000000..c84e153 --- /dev/null +++ b/Source/QtDialog/QCMake.cxx @@ -0,0 +1,462 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#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; + 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)); + } + } +} + +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); +} + +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) { + cmState::CacheEntryType t = state->GetCacheEntryType(*it); + if (t == cmState::INTERNAL || t == cmState::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 s, toremove) { + this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data()); + + state->RemoveCacheEntry(s.toLocal8Bit().data()); + } + + // add some new properites + foreach (QCMakeProperty 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(), cmState::BOOL); + } else if (s.Type == QCMakeProperty::STRING) { + this->CMakeInstance->AddCacheEntry( + s.Key.toLocal8Bit().data(), s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmState::STRING); + } else if (s.Type == QCMakeProperty::PATH) { + this->CMakeInstance->AddCacheEntry( + s.Key.toLocal8Bit().data(), s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmState::PATH); + } else if (s.Type == QCMakeProperty::FILEPATH) { + this->CMakeInstance->AddCacheEntry( + s.Key.toLocal8Bit().data(), s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmState::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) { + cmState::CacheEntryType t = state->GetCacheEntryType(*i); + if (t == cmState::INTERNAL || t == cmState::STATIC || + t == cmState::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 == cmState::BOOL) { + prop.Type = QCMakeProperty::BOOL; + prop.Value = cmSystemTools::IsOn(cachedValue); + } else if (t == cmState::PATH) { + prop.Type = QCMakeProperty::PATH; + } else if (t == cmState::FILEPATH) { + prop.Type = QCMakeProperty::FILEPATH; + } else if (t == cmState::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; +} |