1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: QCMake.cxx,v $
6 Date: $Date: 2009-03-30 20:34:28 $
7 Version: $Revision: 1.26 $
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 =========================================================================*/
21 #include <QCoreApplication>
24 #include "cmCacheManager.h"
25 #include "cmSystemTools.h"
26 #include "cmExternalMakefileProjectGenerator.h"
28 QCMake::QCMake(QObject
* p
)
31 this->SuppressDevWarnings
= false;
32 qRegisterMetaType
<QCMakeProperty
>();
33 qRegisterMetaType
<QCMakePropertyList
>();
35 QDir
execDir(QCoreApplication::applicationDirPath());
38 if(execDir
.exists("../bin/cmake"))
44 execDir
.cd("../../../"); // path to cmake in build directory (need to fix for deployment)
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());
59 this->CMakeInstance
->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui");
61 this->CMakeInstance
->SetCMakeEditCommand("cmake-gui");
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());
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
)
88 cmSystemTools::GetActualCaseForPath(_dir
.toAscii().data()).c_str();
89 if(this->SourceDirectory
!= dir
)
91 this->SourceDirectory
= QDir::fromNativeSeparators(dir
);
92 emit
this->sourceDirChanged(this->SourceDirectory
);
96 void QCMake::setBinaryDirectory(const QString
& _dir
)
99 cmSystemTools::GetActualCaseForPath(_dir
.toAscii().data()).c_str();
100 if(this->BinaryDirectory
!= dir
)
102 this->BinaryDirectory
= QDir::fromNativeSeparators(dir
);
103 emit
this->binaryDirChanged(this->BinaryDirectory
);
104 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
105 this->setGenerator(QString());
106 if(!this->CMakeInstance
->GetCacheManager()->LoadCache(
107 this->BinaryDirectory
.toLocal8Bit().data()))
109 QDir
testDir(this->BinaryDirectory
);
110 if(testDir
.exists("CMakeCache.txt"))
112 cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
113 "tree but cmake does not have permission to read it. "
114 "Please check the permissions of the directory you are trying to run CMake on.");
118 QCMakePropertyList props
= this->properties();
119 emit
this->propertiesChanged(props
);
120 cmCacheManager::CacheIterator itm
= cachem
->NewIterator();
121 if ( itm
.Find("CMAKE_HOME_DIRECTORY"))
123 setSourceDirectory(itm
.GetValue());
125 if ( itm
.Find("CMAKE_GENERATOR"))
127 const char* extraGen
= cachem
->GetCacheValue("CMAKE_EXTRA_GENERATOR");
128 std::string curGen
= cmExternalMakefileProjectGenerator::
129 CreateFullGeneratorName(itm
.GetValue(), extraGen
);
130 this->setGenerator(curGen
.c_str());
136 void QCMake::setGenerator(const QString
& gen
)
138 if(this->Generator
!= gen
)
140 this->Generator
= gen
;
141 emit
this->generatorChanged(this->Generator
);
145 void QCMake::configure()
147 this->CMakeInstance
->SetHomeDirectory(this->SourceDirectory
.toAscii().data());
148 this->CMakeInstance
->SetStartDirectory(this->SourceDirectory
.toAscii().data());
149 this->CMakeInstance
->SetHomeOutputDirectory(this->BinaryDirectory
.toAscii().data());
150 this->CMakeInstance
->SetStartOutputDirectory(this->BinaryDirectory
.toAscii().data());
151 this->CMakeInstance
->SetGlobalGenerator(
152 this->CMakeInstance
->CreateGlobalGenerator(this->Generator
.toAscii().data()));
153 this->CMakeInstance
->LoadCache();
154 this->CMakeInstance
->SetSuppressDevWarnings(this->SuppressDevWarnings
);
155 this->CMakeInstance
->PreLoadCMakeFiles();
157 cmSystemTools::ResetErrorOccuredFlag();
159 int err
= this->CMakeInstance
->Configure();
161 emit
this->propertiesChanged(this->properties());
162 emit
this->configureDone(err
);
165 void QCMake::generate()
167 cmSystemTools::ResetErrorOccuredFlag();
168 int err
= this->CMakeInstance
->Generate();
169 emit
this->generateDone(err
);
172 void QCMake::setProperties(const QCMakePropertyList
& newProps
)
174 QCMakePropertyList props
= newProps
;
176 QStringList toremove
;
178 // set the value of properties
179 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
180 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
181 !i
.IsAtEnd(); i
.Next())
184 if(i
.GetType() == cmCacheManager::INTERNAL
||
185 i
.GetType() == cmCacheManager::STATIC
)
191 prop
.Key
= i
.GetName();
192 int idx
= props
.indexOf(prop
);
195 toremove
.append(i
.GetName());
200 if(prop
.Value
.type() == QVariant::Bool
)
202 i
.SetValue(prop
.Value
.toBool() ? "ON" : "OFF");
206 i
.SetValue(prop
.Value
.toString().toAscii().data());
213 // remove some properites
214 foreach(QString s
, toremove
)
216 cachem
->RemoveCacheEntry(s
.toAscii().data());
219 // add some new properites
220 foreach(QCMakeProperty s
, props
)
222 if(s
.Type
== QCMakeProperty::BOOL
)
224 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
225 s
.Value
.toBool() ? "ON" : "OFF",
226 s
.Help
.toAscii().data(),
227 cmCacheManager::BOOL
);
229 else if(s
.Type
== QCMakeProperty::STRING
)
231 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
232 s
.Value
.toString().toAscii().data(),
233 s
.Help
.toAscii().data(),
234 cmCacheManager::STRING
);
236 else if(s
.Type
== QCMakeProperty::PATH
)
238 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
239 s
.Value
.toString().toAscii().data(),
240 s
.Help
.toAscii().data(),
241 cmCacheManager::PATH
);
243 else if(s
.Type
== QCMakeProperty::FILEPATH
)
245 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
246 s
.Value
.toString().toAscii().data(),
247 s
.Help
.toAscii().data(),
248 cmCacheManager::FILEPATH
);
252 cachem
->SaveCache(this->BinaryDirectory
.toAscii().data());
255 QCMakePropertyList
QCMake::properties() const
257 QCMakePropertyList ret
;
259 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
260 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
261 !i
.IsAtEnd(); i
.Next())
264 if(i
.GetType() == cmCacheManager::INTERNAL
||
265 i
.GetType() == cmCacheManager::STATIC
||
266 i
.GetType() == cmCacheManager::UNINITIALIZED
)
272 prop
.Key
= i
.GetName();
273 prop
.Help
= i
.GetProperty("HELPSTRING");
274 prop
.Value
= i
.GetValue();
275 prop
.Advanced
= i
.GetPropertyAsBool("ADVANCED");
277 if(i
.GetType() == cmCacheManager::BOOL
)
279 prop
.Type
= QCMakeProperty::BOOL
;
280 prop
.Value
= cmSystemTools::IsOn(i
.GetValue());
282 else if(i
.GetType() == cmCacheManager::PATH
)
284 prop
.Type
= QCMakeProperty::PATH
;
286 else if(i
.GetType() == cmCacheManager::FILEPATH
)
288 prop
.Type
= QCMakeProperty::FILEPATH
;
290 else if(i
.GetType() == cmCacheManager::STRING
)
292 prop
.Type
= QCMakeProperty::STRING
;
293 if (i
.PropertyExists("STRINGS"))
295 prop
.Strings
= QString(i
.GetProperty("STRINGS")).split(";");
305 void QCMake::interrupt()
307 cmSystemTools::SetFatalErrorOccured();
310 void QCMake::progressCallback(const char* msg
, float percent
, void* cd
)
312 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
315 emit self
->progressChanged(msg
, percent
);
319 emit self
->outputMessage(msg
);
321 QCoreApplication::processEvents();
324 void QCMake::errorCallback(const char* msg
, const char* /*title*/,
325 bool& /*stop*/, void* cd
)
327 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
328 emit self
->errorMessage(msg
);
329 QCoreApplication::processEvents();
332 QString
QCMake::binaryDirectory() const
334 return this->BinaryDirectory
;
337 QString
QCMake::sourceDirectory() const
339 return this->SourceDirectory
;
342 QString
QCMake::generator() const
344 return this->Generator
;
347 QStringList
QCMake::availableGenerators() const
349 return this->AvailableGenerators
;
352 void QCMake::deleteCache()
355 this->CMakeInstance
->GetCacheManager()->DeleteCache(this->BinaryDirectory
.toAscii().data());
356 // reload to make our cache empty
357 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
358 // emit no generator and no properties
359 this->setGenerator(QString());
360 QCMakePropertyList props
= this->properties();
361 emit
this->propertiesChanged(props
);
364 void QCMake::reloadCache()
366 // emit that the cache was cleaned out
367 QCMakePropertyList props
;
368 emit
this->propertiesChanged(props
);
370 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
371 // emit new cache properties
372 props
= this->properties();
373 emit
this->propertiesChanged(props
);
376 void QCMake::setDebugOutput(bool flag
)
378 if(flag
!= this->CMakeInstance
->GetDebugOutput())
380 this->CMakeInstance
->SetDebugOutputOn(flag
);
381 emit
this->debugOutputChanged(flag
);
385 bool QCMake::getDebugOutput() const
387 return this->CMakeInstance
->GetDebugOutput();
391 void QCMake::setSuppressDevWarnings(bool value
)
393 this->SuppressDevWarnings
= value
;