diff options
Diffstat (limited to 'Source/QtDialog/QCMake.cxx')
-rw-r--r-- | Source/QtDialog/QCMake.cxx | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx new file mode 100644 index 000000000..8554ff894 --- /dev/null +++ b/Source/QtDialog/QCMake.cxx @@ -0,0 +1,448 @@ +/*============================================================================ + 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 <QDir> +#include <QCoreApplication> + +#include "cmake.h" +#include "cmCacheManager.h" +#include "cmSystemTools.h" +#include "cmExternalMakefileProjectGenerator.h" + +#ifdef Q_OS_WIN +#include "qt_windows.h" // For SetErrorMode +#endif + +QCMake::QCMake(QObject* p) + : QObject(p) +{ + this->SuppressDevWarnings = false; + this->WarnUninitializedMode = false; + this->WarnUnusedMode = false; + qRegisterMetaType<QCMakeProperty>(); + qRegisterMetaType<QCMakePropertyList>(); + + QDir execDir(QCoreApplication::applicationDirPath()); + +#if defined(Q_OS_MAC) + if(execDir.exists("../bin/cmake")) + { + execDir.cd("../bin"); + } + else + { + execDir.cd("../../../"); // path to cmake in build directory (need to fix for deployment) + } +#endif + + QString cmakeCommand = QString("cmake")+QString::fromLocal8Bit(cmSystemTools::GetExecutableExtension()); + cmakeCommand = execDir.filePath(cmakeCommand); + + cmSystemTools::DisableRunCommandOutput(); + cmSystemTools::SetRunCommandHideConsole(true); + cmSystemTools::SetErrorCallback(QCMake::errorCallback, this); + cmSystemTools::FindExecutableDirectory(cmakeCommand.toLocal8Bit().data()); + + this->CMakeInstance = new cmake; + this->CMakeInstance->SetCMakeCommand(cmakeCommand.toLocal8Bit().data()); +#if defined(Q_OS_MAC) + this->CMakeInstance->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui"); +#else + this->CMakeInstance->SetCMakeEditCommand("cmake-gui"); +#endif + this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this); + + cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this); + + std::vector<std::string> generators; + this->CMakeInstance->GetRegisteredGenerators(generators); + std::vector<std::string>::iterator iter; + for(iter = generators.begin(); iter != generators.end(); ++iter) + { + // 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 (*iter == "KDevelop3") + { + continue; + } + this->AvailableGenerators.append(QString::fromLocal8Bit(iter->c_str())); + } +} + +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); + cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); + this->setGenerator(QString()); + if(!this->CMakeInstance->GetCacheManager()->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); + cmCacheManager::CacheIterator itm = cachem->NewIterator(); + if ( itm.Find("CMAKE_HOME_DIRECTORY")) + { + setSourceDirectory(QString::fromLocal8Bit(itm.GetValue())); + } + if ( itm.Find("CMAKE_GENERATOR")) + { + const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR"); + std::string curGen = cmExternalMakefileProjectGenerator:: + CreateFullGeneratorName(itm.GetValue(), extraGen); + this->setGenerator(QString::fromLocal8Bit(curGen.c_str())); + } + } +} + + +void QCMake::setGenerator(const QString& gen) +{ + if(this->Generator != gen) + { + this->Generator = gen; + emit this->generatorChanged(this->Generator); + } +} + +void QCMake::configure() +{ +#ifdef Q_OS_WIN + UINT lastErrorMode = SetErrorMode(0); +#endif + + this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetGlobalGenerator( + this->CMakeInstance->CreateGlobalGenerator(this->Generator.toLocal8Bit().data())); + this->CMakeInstance->LoadCache(); + this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings); + 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 + cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); + for(cmCacheManager::CacheIterator i = cachem->NewIterator(); + !i.IsAtEnd(); i.Next()) + { + + if(i.GetType() == cmCacheManager::INTERNAL || + i.GetType() == cmCacheManager::STATIC) + { + continue; + } + + QCMakeProperty prop; + prop.Key = QString::fromLocal8Bit(i.GetName()); + int idx = props.indexOf(prop); + if(idx == -1) + { + toremove.append(QString::fromLocal8Bit(i.GetName())); + } + else + { + prop = props[idx]; + if(prop.Value.type() == QVariant::Bool) + { + i.SetValue(prop.Value.toBool() ? "ON" : "OFF"); + } + else + { + i.SetValue(prop.Value.toString().toLocal8Bit().data()); + } + props.removeAt(idx); + } + + } + + // remove some properites + foreach(QString s, toremove) + { + this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data()); + + cachem->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(), + cmCacheManager::BOOL); + } + else if(s.Type == QCMakeProperty::STRING) + { + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), + cmCacheManager::STRING); + } + else if(s.Type == QCMakeProperty::PATH) + { + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), + cmCacheManager::PATH); + } + else if(s.Type == QCMakeProperty::FILEPATH) + { + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), + cmCacheManager::FILEPATH); + } + } + + cachem->SaveCache(this->BinaryDirectory.toLocal8Bit().data()); +} + +QCMakePropertyList QCMake::properties() const +{ + QCMakePropertyList ret; + + cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); + for(cmCacheManager::CacheIterator i = cachem->NewIterator(); + !i.IsAtEnd(); i.Next()) + { + + if(i.GetType() == cmCacheManager::INTERNAL || + i.GetType() == cmCacheManager::STATIC || + i.GetType() == cmCacheManager::UNINITIALIZED) + { + continue; + } + + QCMakeProperty prop; + prop.Key = QString::fromLocal8Bit(i.GetName()); + prop.Help = QString::fromLocal8Bit(i.GetProperty("HELPSTRING")); + prop.Value = QString::fromLocal8Bit(i.GetValue()); + prop.Advanced = i.GetPropertyAsBool("ADVANCED"); + + if(i.GetType() == cmCacheManager::BOOL) + { + prop.Type = QCMakeProperty::BOOL; + prop.Value = cmSystemTools::IsOn(i.GetValue()); + } + else if(i.GetType() == cmCacheManager::PATH) + { + prop.Type = QCMakeProperty::PATH; + } + else if(i.GetType() == cmCacheManager::FILEPATH) + { + prop.Type = QCMakeProperty::FILEPATH; + } + else if(i.GetType() == cmCacheManager::STRING) + { + prop.Type = QCMakeProperty::STRING; + if (i.PropertyExists("STRINGS")) + { + prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";"); + } + } + + ret.append(prop); + } + + return ret; +} + +void QCMake::interrupt() +{ + this->InterruptFlag.ref(); +} + +bool QCMake::interruptCallback(void* cd) +{ + QCMake* self = reinterpret_cast<QCMake*>(cd); + return self->InterruptFlag; +} + +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::errorCallback(const char* msg, const char* /*title*/, + bool& /*stop*/, void* cd) +{ + QCMake* self = reinterpret_cast<QCMake*>(cd); + emit self->errorMessage(QString::fromLocal8Bit(msg)); + QCoreApplication::processEvents(); +} + +QString QCMake::binaryDirectory() const +{ + return this->BinaryDirectory; +} + +QString QCMake::sourceDirectory() const +{ + return this->SourceDirectory; +} + +QString QCMake::generator() const +{ + return this->Generator; +} + +QStringList QCMake::availableGenerators() const +{ + return this->AvailableGenerators; +} + +void QCMake::deleteCache() +{ + // delete cache + this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data()); + // reload to make our cache empty + this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); + // emit no generator and no properties + this->setGenerator(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->GetCacheManager()->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(); +} + + +void QCMake::setSuppressDevWarnings(bool value) +{ + this->SuppressDevWarnings = value; +} + +void QCMake::setWarnUninitializedMode(bool value) +{ + this->WarnUninitializedMode = value; +} + +void QCMake::setWarnUnusedMode(bool value) +{ + this->WarnUnusedMode = value; +} |