ENH: Add cross compiling support in the GUI in the same dialog that prompts for
[cmake.git] / Source / QtDialog / QCMake.cxx
blob4305877117fac954de9805ba9038064aacca7a7a
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: QCMake.cxx,v $
5 Language: C++
6 Date: $Date: 2008-05-15 23:21:01 $
7 Version: $Revision: 1.24 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
18 #include "QCMake.h"
20 #include <QDir>
21 #include <QCoreApplication>
23 #include "cmake.h"
24 #include "cmCacheManager.h"
25 #include "cmSystemTools.h"
26 #include "cmExternalMakefileProjectGenerator.h"
28 QCMake::QCMake(QObject* p)
29 : QObject(p)
31 this->SuppressDevWarnings = false;
32 qRegisterMetaType<QCMakeProperty>();
33 qRegisterMetaType<QCMakePropertyList>();
35 QDir execDir(QCoreApplication::applicationDirPath());
37 #if defined(Q_OS_MAC)
38 if(execDir.exists("../bin/cmake"))
40 execDir.cd("../bin");
42 else
44 execDir.cd("../../../"); // path to cmake in build directory (need to fix for deployment)
46 #endif
48 QString cmakeCommand = QString("cmake")+cmSystemTools::GetExecutableExtension();
49 cmakeCommand = execDir.filePath(cmakeCommand);
51 cmSystemTools::DisableRunCommandOutput();
52 cmSystemTools::SetRunCommandHideConsole(true);
53 cmSystemTools::SetErrorCallback(QCMake::errorCallback, this);
54 cmSystemTools::FindExecutableDirectory(cmakeCommand.toAscii().data());
56 this->CMakeInstance = new cmake;
57 this->CMakeInstance->SetCMakeCommand(cmakeCommand.toAscii().data());
58 #if defined(Q_OS_MAC)
59 this->CMakeInstance->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui");
60 #else
61 this->CMakeInstance->SetCMakeEditCommand("cmake-gui");
62 #endif
63 this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
65 std::vector<std::string> generators;
66 this->CMakeInstance->GetRegisteredGenerators(generators);
67 std::vector<std::string>::iterator iter;
68 for(iter = generators.begin(); iter != generators.end(); ++iter)
70 this->AvailableGenerators.append(iter->c_str());
74 QCMake::~QCMake()
76 delete this->CMakeInstance;
77 //cmDynamicLoader::FlushCache();
80 void QCMake::loadCache(const QString& dir)
82 this->setBinaryDirectory(dir);
85 void QCMake::setSourceDirectory(const QString& dir)
87 if(this->SourceDirectory != dir)
89 this->SourceDirectory = QDir::fromNativeSeparators(dir);
90 emit this->sourceDirChanged(this->SourceDirectory);
94 void QCMake::setBinaryDirectory(const QString& dir)
96 if(this->BinaryDirectory != dir)
98 this->BinaryDirectory = QDir::fromNativeSeparators(dir);
99 emit this->binaryDirChanged(this->BinaryDirectory);
100 cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
101 this->setGenerator(QString());
102 if(!this->CMakeInstance->GetCacheManager()->LoadCache(
103 this->BinaryDirectory.toLocal8Bit().data()))
105 QDir testDir(this->BinaryDirectory);
106 if(testDir.exists("CMakeCache.txt"))
108 cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
109 "tree but cmake does not have permission to read it. "
110 "Please check the permissions of the directory you are trying to run CMake on.");
114 QCMakePropertyList props = this->properties();
115 emit this->propertiesChanged(props);
116 cmCacheManager::CacheIterator itm = cachem->NewIterator();
117 if ( itm.Find("CMAKE_HOME_DIRECTORY"))
119 setSourceDirectory(itm.GetValue());
121 if ( itm.Find("CMAKE_GENERATOR"))
123 const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR");
124 std::string curGen = cmExternalMakefileProjectGenerator::
125 CreateFullGeneratorName(itm.GetValue(), extraGen);
126 this->setGenerator(curGen.c_str());
132 void QCMake::setGenerator(const QString& gen)
134 if(this->Generator != gen)
136 this->Generator = gen;
137 emit this->generatorChanged(this->Generator);
141 void QCMake::configure()
143 this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toAscii().data());
144 this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toAscii().data());
145 this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toAscii().data());
146 this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toAscii().data());
147 this->CMakeInstance->SetGlobalGenerator(
148 this->CMakeInstance->CreateGlobalGenerator(this->Generator.toAscii().data()));
149 this->CMakeInstance->LoadCache();
150 this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings);
151 this->CMakeInstance->PreLoadCMakeFiles();
153 cmSystemTools::ResetErrorOccuredFlag();
155 int err = this->CMakeInstance->Configure();
157 emit this->propertiesChanged(this->properties());
158 emit this->configureDone(err);
161 void QCMake::generate()
163 cmSystemTools::ResetErrorOccuredFlag();
164 int err = this->CMakeInstance->Generate();
165 emit this->generateDone(err);
168 void QCMake::setProperties(const QCMakePropertyList& newProps)
170 QCMakePropertyList props = newProps;
172 QStringList toremove;
174 // set the value of properties
175 cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
176 for(cmCacheManager::CacheIterator i = cachem->NewIterator();
177 !i.IsAtEnd(); i.Next())
180 if(i.GetType() == cmCacheManager::INTERNAL ||
181 i.GetType() == cmCacheManager::STATIC)
183 continue;
186 QCMakeProperty prop;
187 prop.Key = i.GetName();
188 int idx = props.indexOf(prop);
189 if(idx == -1)
191 toremove.append(i.GetName());
193 else
195 prop = props[idx];
196 if(prop.Value.type() == QVariant::Bool)
198 i.SetValue(prop.Value.toBool() ? "ON" : "OFF");
200 else
202 i.SetValue(prop.Value.toString().toAscii().data());
204 props.removeAt(idx);
209 // remove some properites
210 foreach(QString s, toremove)
212 cachem->RemoveCacheEntry(s.toAscii().data());
215 // add some new properites
216 foreach(QCMakeProperty s, props)
218 if(s.Type == QCMakeProperty::BOOL)
220 this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(),
221 s.Value.toBool() ? "ON" : "OFF",
222 s.Help.toAscii().data(),
223 cmCacheManager::BOOL);
225 else if(s.Type == QCMakeProperty::STRING)
227 this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(),
228 s.Value.toString().toAscii().data(),
229 s.Help.toAscii().data(),
230 cmCacheManager::STRING);
232 else if(s.Type == QCMakeProperty::PATH)
234 this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(),
235 s.Value.toString().toAscii().data(),
236 s.Help.toAscii().data(),
237 cmCacheManager::PATH);
239 else if(s.Type == QCMakeProperty::FILEPATH)
241 this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(),
242 s.Value.toString().toAscii().data(),
243 s.Help.toAscii().data(),
244 cmCacheManager::FILEPATH);
248 cachem->SaveCache(this->BinaryDirectory.toAscii().data());
251 QCMakePropertyList QCMake::properties() const
253 QCMakePropertyList ret;
255 cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
256 for(cmCacheManager::CacheIterator i = cachem->NewIterator();
257 !i.IsAtEnd(); i.Next())
260 if(i.GetType() == cmCacheManager::INTERNAL ||
261 i.GetType() == cmCacheManager::STATIC ||
262 i.GetType() == cmCacheManager::UNINITIALIZED)
264 continue;
267 QCMakeProperty prop;
268 prop.Key = i.GetName();
269 prop.Help = i.GetProperty("HELPSTRING");
270 prop.Value = i.GetValue();
271 prop.Advanced = i.GetPropertyAsBool("ADVANCED");
273 if(i.GetType() == cmCacheManager::BOOL)
275 prop.Type = QCMakeProperty::BOOL;
276 prop.Value = cmSystemTools::IsOn(i.GetValue());
278 else if(i.GetType() == cmCacheManager::PATH)
280 prop.Type = QCMakeProperty::PATH;
282 else if(i.GetType() == cmCacheManager::FILEPATH)
284 prop.Type = QCMakeProperty::FILEPATH;
286 else if(i.GetType() == cmCacheManager::STRING)
288 prop.Type = QCMakeProperty::STRING;
291 ret.append(prop);
294 return ret;
297 void QCMake::interrupt()
299 cmSystemTools::SetFatalErrorOccured();
302 void QCMake::progressCallback(const char* msg, float percent, void* cd)
304 QCMake* self = reinterpret_cast<QCMake*>(cd);
305 if(percent >= 0)
307 emit self->progressChanged(msg, percent);
309 else
311 emit self->outputMessage(msg);
313 QCoreApplication::processEvents();
316 void QCMake::errorCallback(const char* msg, const char* /*title*/,
317 bool& /*stop*/, void* cd)
319 QCMake* self = reinterpret_cast<QCMake*>(cd);
320 emit self->errorMessage(msg);
321 QCoreApplication::processEvents();
324 QString QCMake::binaryDirectory() const
326 return this->BinaryDirectory;
329 QString QCMake::sourceDirectory() const
331 return this->SourceDirectory;
334 QString QCMake::generator() const
336 return this->Generator;
339 QStringList QCMake::availableGenerators() const
341 return this->AvailableGenerators;
344 void QCMake::deleteCache()
346 // delete cache
347 this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toAscii().data());
348 // reload to make our cache empty
349 this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toAscii().data());
350 // emit no generator and no properties
351 this->setGenerator(QString());
352 QCMakePropertyList props = this->properties();
353 emit this->propertiesChanged(props);
356 void QCMake::reloadCache()
358 // emit that the cache was cleaned out
359 QCMakePropertyList props;
360 emit this->propertiesChanged(props);
361 // reload
362 this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toAscii().data());
363 // emit new cache properties
364 props = this->properties();
365 emit this->propertiesChanged(props);
368 void QCMake::setDebugOutput(bool flag)
370 if(flag != this->CMakeInstance->GetDebugOutput())
372 this->CMakeInstance->SetDebugOutputOn(flag);
373 emit this->debugOutputChanged(flag);
377 bool QCMake::getDebugOutput() const
379 return this->CMakeInstance->GetDebugOutput();
383 void QCMake::setSuppressDevWarnings(bool value)
385 this->SuppressDevWarnings = value;