1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: QCMake.cxx,v $
6 Date: $Date: 2008-04-02 21:41:24 $
7 Version: $Revision: 1.22 $
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
<QCMakeCacheProperty
>();
33 qRegisterMetaType
<QCMakeCachePropertyList
>();
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
)
87 if(this->SourceDirectory
!= dir
)
89 this->SourceDirectory
= dir
;
90 emit
this->sourceDirChanged(dir
);
94 void QCMake::setBinaryDirectory(const QString
& dir
)
96 if(this->BinaryDirectory
!= dir
)
98 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
99 this->BinaryDirectory
= dir
;
100 this->setGenerator(QString());
101 if(!this->CMakeInstance
->GetCacheManager()->LoadCache(dir
.toLocal8Bit().data()))
104 if(testDir
.exists("CMakeCache.txt"))
106 cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
107 "tree but cmake does not have permission to read it. "
108 "Please check the permissions of the directory you are trying to run CMake on.");
112 QCMakeCachePropertyList props
= this->properties();
113 emit
this->propertiesChanged(props
);
114 cmCacheManager::CacheIterator itm
= cachem
->NewIterator();
115 if ( itm
.Find("CMAKE_HOME_DIRECTORY"))
117 setSourceDirectory(itm
.GetValue());
119 if ( itm
.Find("CMAKE_GENERATOR"))
121 const char* extraGen
= cachem
->GetCacheValue("CMAKE_EXTRA_GENERATOR");
122 std::string curGen
= cmExternalMakefileProjectGenerator::
123 CreateFullGeneratorName(itm
.GetValue(), extraGen
);
124 this->setGenerator(curGen
.c_str());
130 void QCMake::setGenerator(const QString
& gen
)
132 if(this->Generator
!= gen
)
134 this->Generator
= gen
;
135 emit
this->generatorChanged(this->Generator
);
139 void QCMake::configure()
141 this->CMakeInstance
->SetHomeDirectory(this->SourceDirectory
.toAscii().data());
142 this->CMakeInstance
->SetStartDirectory(this->SourceDirectory
.toAscii().data());
143 this->CMakeInstance
->SetHomeOutputDirectory(this->BinaryDirectory
.toAscii().data());
144 this->CMakeInstance
->SetStartOutputDirectory(this->BinaryDirectory
.toAscii().data());
145 this->CMakeInstance
->SetGlobalGenerator(
146 this->CMakeInstance
->CreateGlobalGenerator(this->Generator
.toAscii().data()));
147 this->CMakeInstance
->LoadCache();
148 this->CMakeInstance
->SetSuppressDevWarnings(this->SuppressDevWarnings
);
149 this->CMakeInstance
->PreLoadCMakeFiles();
151 cmSystemTools::ResetErrorOccuredFlag();
153 int err
= this->CMakeInstance
->Configure();
155 emit
this->propertiesChanged(this->properties());
156 emit
this->configureDone(err
);
159 void QCMake::generate()
161 cmSystemTools::ResetErrorOccuredFlag();
162 int err
= this->CMakeInstance
->Generate();
163 emit
this->generateDone(err
);
166 void QCMake::setProperties(const QCMakeCachePropertyList
& newProps
)
168 QCMakeCachePropertyList props
= newProps
;
170 QStringList toremove
;
172 // set the value of properties
173 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
174 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
175 !i
.IsAtEnd(); i
.Next())
178 if(i
.GetType() == cmCacheManager::INTERNAL
||
179 i
.GetType() == cmCacheManager::STATIC
)
184 QCMakeCacheProperty prop
;
185 prop
.Key
= i
.GetName();
186 int idx
= props
.indexOf(prop
);
189 toremove
.append(i
.GetName());
194 if(prop
.Value
.type() == QVariant::Bool
)
196 i
.SetValue(prop
.Value
.toBool() ? "ON" : "OFF");
200 i
.SetValue(prop
.Value
.toString().toAscii().data());
207 // remove some properites
208 foreach(QString s
, toremove
)
210 cachem
->RemoveCacheEntry(s
.toAscii().data());
213 // add some new properites
214 foreach(QCMakeCacheProperty s
, props
)
216 if(s
.Type
== QCMakeCacheProperty::BOOL
)
218 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
219 s
.Value
.toBool() ? "ON" : "OFF",
220 s
.Help
.toAscii().data(),
221 cmCacheManager::BOOL
);
223 else if(s
.Type
== QCMakeCacheProperty::STRING
)
225 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
226 s
.Value
.toString().toAscii().data(),
227 s
.Help
.toAscii().data(),
228 cmCacheManager::STRING
);
230 else if(s
.Type
== QCMakeCacheProperty::PATH
)
232 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
233 s
.Value
.toString().toAscii().data(),
234 s
.Help
.toAscii().data(),
235 cmCacheManager::PATH
);
237 else if(s
.Type
== QCMakeCacheProperty::FILEPATH
)
239 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
240 s
.Value
.toString().toAscii().data(),
241 s
.Help
.toAscii().data(),
242 cmCacheManager::FILEPATH
);
246 cachem
->SaveCache(this->BinaryDirectory
.toAscii().data());
249 QCMakeCachePropertyList
QCMake::properties() const
251 QCMakeCachePropertyList ret
;
253 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
254 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
255 !i
.IsAtEnd(); i
.Next())
258 if(i
.GetType() == cmCacheManager::INTERNAL
||
259 i
.GetType() == cmCacheManager::STATIC
||
260 i
.GetType() == cmCacheManager::UNINITIALIZED
)
265 QCMakeCacheProperty prop
;
266 prop
.Key
= i
.GetName();
267 prop
.Help
= i
.GetProperty("HELPSTRING");
268 prop
.Value
= i
.GetValue();
269 prop
.Advanced
= i
.GetPropertyAsBool("ADVANCED");
271 if(i
.GetType() == cmCacheManager::BOOL
)
273 prop
.Type
= QCMakeCacheProperty::BOOL
;
274 prop
.Value
= cmSystemTools::IsOn(i
.GetValue());
276 else if(i
.GetType() == cmCacheManager::PATH
)
278 prop
.Type
= QCMakeCacheProperty::PATH
;
280 else if(i
.GetType() == cmCacheManager::FILEPATH
)
282 prop
.Type
= QCMakeCacheProperty::FILEPATH
;
284 else if(i
.GetType() == cmCacheManager::STRING
)
286 prop
.Type
= QCMakeCacheProperty::STRING
;
295 void QCMake::interrupt()
297 cmSystemTools::SetFatalErrorOccured();
300 void QCMake::progressCallback(const char* msg
, float percent
, void* cd
)
302 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
305 emit self
->progressChanged(msg
, percent
);
309 emit self
->outputMessage(msg
);
311 QCoreApplication::processEvents();
314 void QCMake::errorCallback(const char* msg
, const char* /*title*/,
315 bool& /*stop*/, void* cd
)
317 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
318 emit self
->errorMessage(msg
);
319 QCoreApplication::processEvents();
322 QString
QCMake::binaryDirectory() const
324 return this->BinaryDirectory
;
327 QString
QCMake::sourceDirectory() const
329 return this->SourceDirectory
;
332 QString
QCMake::generator() const
334 return this->Generator
;
337 QStringList
QCMake::availableGenerators() const
339 return this->AvailableGenerators
;
342 void QCMake::deleteCache()
345 this->CMakeInstance
->GetCacheManager()->DeleteCache(this->BinaryDirectory
.toAscii().data());
346 // reload to make our cache empty
347 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
348 // emit no generator and no properties
349 this->setGenerator(QString());
350 QCMakeCachePropertyList props
= this->properties();
351 emit
this->propertiesChanged(props
);
354 void QCMake::reloadCache()
356 // emit that the cache was cleaned out
357 QCMakeCachePropertyList props
;
358 emit
this->propertiesChanged(props
);
360 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
361 // emit new cache properties
362 props
= this->properties();
363 emit
this->propertiesChanged(props
);
366 void QCMake::setDebugOutput(bool flag
)
368 if(flag
!= this->CMakeInstance
->GetDebugOutput())
370 this->CMakeInstance
->SetDebugOutputOn(flag
);
371 emit
this->debugOutputChanged(flag
);
375 bool QCMake::getDebugOutput() const
377 return this->CMakeInstance
->GetDebugOutput();
381 void QCMake::SetSuppressDevWarnings(bool value
)
383 this->SuppressDevWarnings
= value
;