1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: QCMake.cxx,v $
6 Date: $Date: 2009-08-10 18:32:08 $
7 Version: $Revision: 1.27 $
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 // Skip the generator "KDevelop3", since there is also
71 // "KDevelop3 - Unix Makefiles", which is the full and official name.
72 // The short name is actually only still there since this was the name
73 // in CMake 2.4, to keep "command line argument compatibility", but
74 // this is not necessary in the GUI.
75 if (*iter
== "KDevelop3")
79 this->AvailableGenerators
.append(iter
->c_str());
85 delete this->CMakeInstance
;
86 //cmDynamicLoader::FlushCache();
89 void QCMake::loadCache(const QString
& dir
)
91 this->setBinaryDirectory(dir
);
94 void QCMake::setSourceDirectory(const QString
& _dir
)
97 cmSystemTools::GetActualCaseForPath(_dir
.toAscii().data()).c_str();
98 if(this->SourceDirectory
!= dir
)
100 this->SourceDirectory
= QDir::fromNativeSeparators(dir
);
101 emit
this->sourceDirChanged(this->SourceDirectory
);
105 void QCMake::setBinaryDirectory(const QString
& _dir
)
108 cmSystemTools::GetActualCaseForPath(_dir
.toAscii().data()).c_str();
109 if(this->BinaryDirectory
!= dir
)
111 this->BinaryDirectory
= QDir::fromNativeSeparators(dir
);
112 emit
this->binaryDirChanged(this->BinaryDirectory
);
113 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
114 this->setGenerator(QString());
115 if(!this->CMakeInstance
->GetCacheManager()->LoadCache(
116 this->BinaryDirectory
.toLocal8Bit().data()))
118 QDir
testDir(this->BinaryDirectory
);
119 if(testDir
.exists("CMakeCache.txt"))
121 cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
122 "tree but cmake does not have permission to read it. "
123 "Please check the permissions of the directory you are trying to run CMake on.");
127 QCMakePropertyList props
= this->properties();
128 emit
this->propertiesChanged(props
);
129 cmCacheManager::CacheIterator itm
= cachem
->NewIterator();
130 if ( itm
.Find("CMAKE_HOME_DIRECTORY"))
132 setSourceDirectory(itm
.GetValue());
134 if ( itm
.Find("CMAKE_GENERATOR"))
136 const char* extraGen
= cachem
->GetCacheValue("CMAKE_EXTRA_GENERATOR");
137 std::string curGen
= cmExternalMakefileProjectGenerator::
138 CreateFullGeneratorName(itm
.GetValue(), extraGen
);
139 this->setGenerator(curGen
.c_str());
145 void QCMake::setGenerator(const QString
& gen
)
147 if(this->Generator
!= gen
)
149 this->Generator
= gen
;
150 emit
this->generatorChanged(this->Generator
);
154 void QCMake::configure()
156 this->CMakeInstance
->SetHomeDirectory(this->SourceDirectory
.toAscii().data());
157 this->CMakeInstance
->SetStartDirectory(this->SourceDirectory
.toAscii().data());
158 this->CMakeInstance
->SetHomeOutputDirectory(this->BinaryDirectory
.toAscii().data());
159 this->CMakeInstance
->SetStartOutputDirectory(this->BinaryDirectory
.toAscii().data());
160 this->CMakeInstance
->SetGlobalGenerator(
161 this->CMakeInstance
->CreateGlobalGenerator(this->Generator
.toAscii().data()));
162 this->CMakeInstance
->LoadCache();
163 this->CMakeInstance
->SetSuppressDevWarnings(this->SuppressDevWarnings
);
164 this->CMakeInstance
->PreLoadCMakeFiles();
166 cmSystemTools::ResetErrorOccuredFlag();
168 int err
= this->CMakeInstance
->Configure();
170 emit
this->propertiesChanged(this->properties());
171 emit
this->configureDone(err
);
174 void QCMake::generate()
176 cmSystemTools::ResetErrorOccuredFlag();
177 int err
= this->CMakeInstance
->Generate();
178 emit
this->generateDone(err
);
181 void QCMake::setProperties(const QCMakePropertyList
& newProps
)
183 QCMakePropertyList props
= newProps
;
185 QStringList toremove
;
187 // set the value of properties
188 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
189 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
190 !i
.IsAtEnd(); i
.Next())
193 if(i
.GetType() == cmCacheManager::INTERNAL
||
194 i
.GetType() == cmCacheManager::STATIC
)
200 prop
.Key
= i
.GetName();
201 int idx
= props
.indexOf(prop
);
204 toremove
.append(i
.GetName());
209 if(prop
.Value
.type() == QVariant::Bool
)
211 i
.SetValue(prop
.Value
.toBool() ? "ON" : "OFF");
215 i
.SetValue(prop
.Value
.toString().toAscii().data());
222 // remove some properites
223 foreach(QString s
, toremove
)
225 cachem
->RemoveCacheEntry(s
.toAscii().data());
228 // add some new properites
229 foreach(QCMakeProperty s
, props
)
231 if(s
.Type
== QCMakeProperty::BOOL
)
233 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
234 s
.Value
.toBool() ? "ON" : "OFF",
235 s
.Help
.toAscii().data(),
236 cmCacheManager::BOOL
);
238 else if(s
.Type
== QCMakeProperty::STRING
)
240 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
241 s
.Value
.toString().toAscii().data(),
242 s
.Help
.toAscii().data(),
243 cmCacheManager::STRING
);
245 else if(s
.Type
== QCMakeProperty::PATH
)
247 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
248 s
.Value
.toString().toAscii().data(),
249 s
.Help
.toAscii().data(),
250 cmCacheManager::PATH
);
252 else if(s
.Type
== QCMakeProperty::FILEPATH
)
254 this->CMakeInstance
->AddCacheEntry(s
.Key
.toAscii().data(),
255 s
.Value
.toString().toAscii().data(),
256 s
.Help
.toAscii().data(),
257 cmCacheManager::FILEPATH
);
261 cachem
->SaveCache(this->BinaryDirectory
.toAscii().data());
264 QCMakePropertyList
QCMake::properties() const
266 QCMakePropertyList ret
;
268 cmCacheManager
*cachem
= this->CMakeInstance
->GetCacheManager();
269 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
270 !i
.IsAtEnd(); i
.Next())
273 if(i
.GetType() == cmCacheManager::INTERNAL
||
274 i
.GetType() == cmCacheManager::STATIC
||
275 i
.GetType() == cmCacheManager::UNINITIALIZED
)
281 prop
.Key
= i
.GetName();
282 prop
.Help
= i
.GetProperty("HELPSTRING");
283 prop
.Value
= i
.GetValue();
284 prop
.Advanced
= i
.GetPropertyAsBool("ADVANCED");
286 if(i
.GetType() == cmCacheManager::BOOL
)
288 prop
.Type
= QCMakeProperty::BOOL
;
289 prop
.Value
= cmSystemTools::IsOn(i
.GetValue());
291 else if(i
.GetType() == cmCacheManager::PATH
)
293 prop
.Type
= QCMakeProperty::PATH
;
295 else if(i
.GetType() == cmCacheManager::FILEPATH
)
297 prop
.Type
= QCMakeProperty::FILEPATH
;
299 else if(i
.GetType() == cmCacheManager::STRING
)
301 prop
.Type
= QCMakeProperty::STRING
;
302 if (i
.PropertyExists("STRINGS"))
304 prop
.Strings
= QString(i
.GetProperty("STRINGS")).split(";");
314 void QCMake::interrupt()
316 cmSystemTools::SetFatalErrorOccured();
319 void QCMake::progressCallback(const char* msg
, float percent
, void* cd
)
321 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
324 emit self
->progressChanged(msg
, percent
);
328 emit self
->outputMessage(msg
);
330 QCoreApplication::processEvents();
333 void QCMake::errorCallback(const char* msg
, const char* /*title*/,
334 bool& /*stop*/, void* cd
)
336 QCMake
* self
= reinterpret_cast<QCMake
*>(cd
);
337 emit self
->errorMessage(msg
);
338 QCoreApplication::processEvents();
341 QString
QCMake::binaryDirectory() const
343 return this->BinaryDirectory
;
346 QString
QCMake::sourceDirectory() const
348 return this->SourceDirectory
;
351 QString
QCMake::generator() const
353 return this->Generator
;
356 QStringList
QCMake::availableGenerators() const
358 return this->AvailableGenerators
;
361 void QCMake::deleteCache()
364 this->CMakeInstance
->GetCacheManager()->DeleteCache(this->BinaryDirectory
.toAscii().data());
365 // reload to make our cache empty
366 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
367 // emit no generator and no properties
368 this->setGenerator(QString());
369 QCMakePropertyList props
= this->properties();
370 emit
this->propertiesChanged(props
);
373 void QCMake::reloadCache()
375 // emit that the cache was cleaned out
376 QCMakePropertyList props
;
377 emit
this->propertiesChanged(props
);
379 this->CMakeInstance
->GetCacheManager()->LoadCache(this->BinaryDirectory
.toAscii().data());
380 // emit new cache properties
381 props
= this->properties();
382 emit
this->propertiesChanged(props
);
385 void QCMake::setDebugOutput(bool flag
)
387 if(flag
!= this->CMakeInstance
->GetDebugOutput())
389 this->CMakeInstance
->SetDebugOutputOn(flag
);
390 emit
this->debugOutputChanged(flag
);
394 bool QCMake::getDebugOutput() const
396 return this->CMakeInstance
->GetDebugOutput();
400 void QCMake::setSuppressDevWarnings(bool value
)
402 this->SuppressDevWarnings
= value
;