1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: QCMake.cxx,v $
6 Date: $Date: 2009-03-12 15:19:26 $
7 Version: $Revision: 1.25 $
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
)
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
)
187 prop
.Key
= i
.GetName();
188 int idx
= props
.indexOf(prop
);
191 toremove
.append(i
.GetName());
196 if(prop
.Value
.type() == QVariant::Bool
)
198 i
.SetValue(prop
.Value
.toBool() ? "ON" : "OFF");
202 i
.SetValue(prop
.Value
.toString().toAscii().data());
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
)
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
;
289 if (i
.PropertyExists("STRINGS"))
291 prop
.Strings
= QString(i
.GetProperty("STRINGS")).split(";");
301 void QCMake::interrupt()
303 cmSystemTools::SetFatalErrorOccured();
306 void QCMake::progressCallback(const char* msg
, float percent
, void* cd
)
308 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
311 emit self
->progressChanged(msg
, percent
);
315 emit self
->outputMessage(msg
);
317 QCoreApplication::processEvents();
320 void QCMake::errorCallback(const char* msg
, const char* /*title*/,
321 bool& /*stop*/, void* cd
)
323 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
324 emit self
->errorMessage(msg
);
325 QCoreApplication::processEvents();
328 QString
QCMake::binaryDirectory() const
330 return this->BinaryDirectory
;
333 QString
QCMake::sourceDirectory() const
335 return this->SourceDirectory
;
338 QString
QCMake::generator() const
340 return this->Generator
;
343 QStringList
QCMake::availableGenerators() const
345 return this->AvailableGenerators
;
348 void QCMake::deleteCache()
351 this->CMakeInstance
->GetCacheManager()->DeleteCache(this->BinaryDirectory
.toAscii().data());
352 // reload to make our cache empty
353 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
354 // emit no generator and no properties
355 this->setGenerator(QString());
356 QCMakePropertyList props
= this->properties();
357 emit
this->propertiesChanged(props
);
360 void QCMake::reloadCache()
362 // emit that the cache was cleaned out
363 QCMakePropertyList props
;
364 emit
this->propertiesChanged(props
);
366 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
367 // emit new cache properties
368 props
= this->properties();
369 emit
this->propertiesChanged(props
);
372 void QCMake::setDebugOutput(bool flag
)
374 if(flag
!= this->CMakeInstance
->GetDebugOutput())
376 this->CMakeInstance
->SetDebugOutputOn(flag
);
377 emit
this->debugOutputChanged(flag
);
381 bool QCMake::getDebugOutput() const
383 return this->CMakeInstance
->GetDebugOutput();
387 void QCMake::setSuppressDevWarnings(bool value
)
389 this->SuppressDevWarnings
= value
;