| 1 |
/*============================================================================ |
|---|
| 2 |
CMake - Cross Platform Makefile Generator |
|---|
| 3 |
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium |
|---|
| 4 |
|
|---|
| 5 |
Distributed under the OSI-approved BSD License (the "License"); |
|---|
| 6 |
see accompanying file Copyright.txt for details. |
|---|
| 7 |
|
|---|
| 8 |
This software is distributed WITHOUT ANY WARRANTY; without even the |
|---|
| 9 |
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 10 |
See the License for more information. |
|---|
| 11 |
============================================================================*/ |
|---|
| 12 |
|
|---|
| 13 |
// //////////////////////////////////////////////////// |
|---|
| 14 |
// Modified by OSRail Project to create a CodeBlocks |
|---|
| 15 |
// generator for gcc projects. sehenley@comcast.net |
|---|
| 16 |
// /////////////////////////////////////////////////// |
|---|
| 17 |
|
|---|
| 18 |
#include "cmake.h" |
|---|
| 19 |
#include "cmDocumentVariables.h" |
|---|
| 20 |
#include "time.h" |
|---|
| 21 |
#include "cmCacheManager.h" |
|---|
| 22 |
#include "cmMakefile.h" |
|---|
| 23 |
#include "cmLocalGenerator.h" |
|---|
| 24 |
#include "cmExternalMakefileProjectGenerator.h" |
|---|
| 25 |
#include "cmCommands.h" |
|---|
| 26 |
#include "cmCommand.h" |
|---|
| 27 |
#include "cmFileTimeComparison.h" |
|---|
| 28 |
#include "cmGeneratedFileStream.h" |
|---|
| 29 |
#include "cmSourceFile.h" |
|---|
| 30 |
#include "cmVersion.h" |
|---|
| 31 |
#include "cmTest.h" |
|---|
| 32 |
#include "cmDocumentationFormatterText.h" |
|---|
| 33 |
|
|---|
| 34 |
#if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 35 |
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback. |
|---|
| 36 |
# include "cmVariableWatch.h" |
|---|
| 37 |
# include <cmsys/Terminal.h> |
|---|
| 38 |
# include <cmsys/CommandLineArguments.hxx> |
|---|
| 39 |
#endif |
|---|
| 40 |
|
|---|
| 41 |
#include <cmsys/Directory.hxx> |
|---|
| 42 |
#include <cmsys/Process.h> |
|---|
| 43 |
#include <cmsys/Glob.hxx> |
|---|
| 44 |
#include <cmsys/RegularExpression.hxx> |
|---|
| 45 |
|
|---|
| 46 |
// only build kdevelop generator on non-windows platforms |
|---|
| 47 |
// when not bootstrapping cmake |
|---|
| 48 |
#if !defined(_WIN32) |
|---|
| 49 |
# if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 50 |
# define CMAKE_USE_KDEVELOP |
|---|
| 51 |
# endif |
|---|
| 52 |
#endif |
|---|
| 53 |
|
|---|
| 54 |
#if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 55 |
# define CMAKE_USE_ECLIPSE |
|---|
| 56 |
#endif |
|---|
| 57 |
|
|---|
| 58 |
#if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 59 |
# define CMAKE_BOOT_MINGW |
|---|
| 60 |
#endif |
|---|
| 61 |
|
|---|
| 62 |
// include the generator |
|---|
| 63 |
#if defined(_WIN32) && !defined(__CYGWIN__) |
|---|
| 64 |
# if !defined(CMAKE_BOOT_MINGW) |
|---|
| 65 |
# include "cmGlobalVisualStudio6Generator.h" |
|---|
| 66 |
# include "cmGlobalVisualStudio7Generator.h" |
|---|
| 67 |
# include "cmGlobalVisualStudio71Generator.h" |
|---|
| 68 |
# include "cmGlobalVisualStudio8Generator.h" |
|---|
| 69 |
# include "cmGlobalVisualStudio9Generator.h" |
|---|
| 70 |
# include "cmGlobalVisualStudio9Win64Generator.h" |
|---|
| 71 |
# include "cmGlobalVisualStudio10Generator.h" |
|---|
| 72 |
# include "cmGlobalVisualStudio10Win64Generator.h" |
|---|
| 73 |
# include "cmGlobalVisualStudio8Win64Generator.h" |
|---|
| 74 |
# include "cmGlobalBorlandMakefileGenerator.h" |
|---|
| 75 |
# include "cmGlobalNMakeMakefileGenerator.h" |
|---|
| 76 |
# include "cmGlobalJOMMakefileGenerator.h" |
|---|
| 77 |
# include "cmGlobalWatcomWMakeGenerator.h" |
|---|
| 78 |
# define CMAKE_HAVE_VS_GENERATORS |
|---|
| 79 |
# endif |
|---|
| 80 |
# include "cmGlobalMSYSMakefileGenerator.h" |
|---|
| 81 |
# include "cmGlobalMinGWMakefileGenerator.h" |
|---|
| 82 |
# include "cmWin32ProcessExecution.h" |
|---|
| 83 |
#else |
|---|
| 84 |
#endif |
|---|
| 85 |
#include "cmGlobalUnixMakefileGenerator3.h" |
|---|
| 86 |
|
|---|
| 87 |
// //////////////////////////////////////////////////// |
|---|
| 88 |
// Modified by OSRail Project to create a CodeBlocks |
|---|
| 89 |
// generator for gcc projects. sehenley@comcast.net |
|---|
| 90 |
// /////////////////////////////////////////////////// |
|---|
| 91 |
#include "cmGlobalCodeBlocksGenerator.h" |
|---|
| 92 |
// /////////////////////////////////////////////////// |
|---|
| 93 |
|
|---|
| 94 |
#if defined(CMAKE_HAVE_VS_GENERATORS) |
|---|
| 95 |
#include "cmCallVisualStudioMacro.h" |
|---|
| 96 |
#endif |
|---|
| 97 |
|
|---|
| 98 |
#if !defined(CMAKE_BOOT_MINGW) |
|---|
| 99 |
# include "cmExtraCodeBlocksGenerator.h" |
|---|
| 100 |
#endif |
|---|
| 101 |
|
|---|
| 102 |
#ifdef CMAKE_USE_KDEVELOP |
|---|
| 103 |
# include "cmGlobalKdevelopGenerator.h" |
|---|
| 104 |
#endif |
|---|
| 105 |
|
|---|
| 106 |
#ifdef CMAKE_USE_ECLIPSE |
|---|
| 107 |
# include "cmExtraEclipseCDT4Generator.h" |
|---|
| 108 |
#endif |
|---|
| 109 |
|
|---|
| 110 |
#include <stdlib.h> // required for atoi |
|---|
| 111 |
|
|---|
| 112 |
#if defined( __APPLE__ ) |
|---|
| 113 |
# if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 114 |
# include "cmGlobalXCodeGenerator.h" |
|---|
| 115 |
# define CMAKE_USE_XCODE 1 |
|---|
| 116 |
# endif |
|---|
| 117 |
# include <sys/types.h> |
|---|
| 118 |
# include <sys/time.h> |
|---|
| 119 |
# include <sys/resource.h> |
|---|
| 120 |
#endif |
|---|
| 121 |
|
|---|
| 122 |
#include <sys/stat.h> // struct stat |
|---|
| 123 |
|
|---|
| 124 |
#include <memory> // auto_ptr |
|---|
| 125 |
|
|---|
| 126 |
static bool cmakeCheckStampFile(const char* stampName); |
|---|
| 127 |
static bool cmakeCheckStampList(const char* stampName); |
|---|
| 128 |
|
|---|
| 129 |
void cmNeedBackwardsCompatibility(const std::string& variable, |
|---|
| 130 |
int access_type, void*, const char*, const cmMakefile*) |
|---|
| 131 |
{ |
|---|
| 132 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 133 |
if (access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS) |
|---|
| 134 |
{ |
|---|
| 135 |
std::string message = "An attempt was made to access a variable: "; |
|---|
| 136 |
message += variable; |
|---|
| 137 |
message += |
|---|
| 138 |
" that has not been defined. Some variables were always defined " |
|---|
| 139 |
"by CMake in versions prior to 1.6. To fix this you might need to set " |
|---|
| 140 |
"the cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If " |
|---|
| 141 |
"you are writing a CMakeList file, (or have already set " |
|---|
| 142 |
"CMAKE_BACKWARDS_COMPATABILITY to 1.4 or less) then you probably need " |
|---|
| 143 |
"to include a CMake module to test for the feature this variable " |
|---|
| 144 |
"defines."; |
|---|
| 145 |
cmSystemTools::Error(message.c_str()); |
|---|
| 146 |
} |
|---|
| 147 |
#else |
|---|
| 148 |
(void)variable; |
|---|
| 149 |
(void)access_type; |
|---|
| 150 |
#endif |
|---|
| 151 |
} |
|---|
| 152 |
|
|---|
| 153 |
cmake::cmake() |
|---|
| 154 |
{ |
|---|
| 155 |
this->Trace = false; |
|---|
| 156 |
this->SuppressDevWarnings = false; |
|---|
| 157 |
this->DoSuppressDevWarnings = false; |
|---|
| 158 |
this->DebugOutput = false; |
|---|
| 159 |
this->DebugTryCompile = false; |
|---|
| 160 |
this->ClearBuildSystem = false; |
|---|
| 161 |
this->FileComparison = new cmFileTimeComparison; |
|---|
| 162 |
|
|---|
| 163 |
this->Policies = new cmPolicies(); |
|---|
| 164 |
this->InitializeProperties(); |
|---|
| 165 |
|
|---|
| 166 |
#ifdef __APPLE__ |
|---|
| 167 |
struct rlimit rlp; |
|---|
| 168 |
if(!getrlimit(RLIMIT_STACK, &rlp)) |
|---|
| 169 |
{ |
|---|
| 170 |
if(rlp.rlim_cur != rlp.rlim_max) |
|---|
| 171 |
{ |
|---|
| 172 |
rlp.rlim_cur = rlp.rlim_max; |
|---|
| 173 |
setrlimit(RLIMIT_STACK, &rlp); |
|---|
| 174 |
} |
|---|
| 175 |
} |
|---|
| 176 |
#endif |
|---|
| 177 |
|
|---|
| 178 |
// If MAKEFLAGS are given in the environment, remove the environment |
|---|
| 179 |
// variable. This will prevent try-compile from succeeding when it |
|---|
| 180 |
// should fail (if "-i" is an option). We cannot simply test |
|---|
| 181 |
// whether "-i" is given and remove it because some make programs |
|---|
| 182 |
// encode the MAKEFLAGS variable in a strange way. |
|---|
| 183 |
if(getenv("MAKEFLAGS")) |
|---|
| 184 |
{ |
|---|
| 185 |
cmSystemTools::PutEnv("MAKEFLAGS="); |
|---|
| 186 |
} |
|---|
| 187 |
|
|---|
| 188 |
this->Verbose = false; |
|---|
| 189 |
this->InTryCompile = false; |
|---|
| 190 |
this->CacheManager = new cmCacheManager(this); |
|---|
| 191 |
this->GlobalGenerator = 0; |
|---|
| 192 |
this->ProgressCallback = 0; |
|---|
| 193 |
this->ProgressCallbackClientData = 0; |
|---|
| 194 |
this->ScriptMode = false; |
|---|
| 195 |
|
|---|
| 196 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 197 |
this->VariableWatch = new cmVariableWatch; |
|---|
| 198 |
this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN", |
|---|
| 199 |
cmNeedBackwardsCompatibility); |
|---|
| 200 |
this->VariableWatch->AddWatch("CMAKE_SIZEOF_INT", |
|---|
| 201 |
cmNeedBackwardsCompatibility); |
|---|
| 202 |
this->VariableWatch->AddWatch("CMAKE_X_LIBS", |
|---|
| 203 |
cmNeedBackwardsCompatibility); |
|---|
| 204 |
#endif |
|---|
| 205 |
|
|---|
| 206 |
this->AddDefaultGenerators(); |
|---|
| 207 |
this->AddDefaultExtraGenerators(); |
|---|
| 208 |
this->AddDefaultCommands(); |
|---|
| 209 |
|
|---|
| 210 |
// Make sure we can capture the build tool output. |
|---|
| 211 |
cmSystemTools::EnableVSConsoleOutput(); |
|---|
| 212 |
} |
|---|
| 213 |
|
|---|
| 214 |
cmake::~cmake() |
|---|
| 215 |
{ |
|---|
| 216 |
delete this->CacheManager; |
|---|
| 217 |
delete this->Policies; |
|---|
| 218 |
if (this->GlobalGenerator) |
|---|
| 219 |
{ |
|---|
| 220 |
delete this->GlobalGenerator; |
|---|
| 221 |
this->GlobalGenerator = 0; |
|---|
| 222 |
} |
|---|
| 223 |
for(RegisteredCommandsMap::iterator j = this->Commands.begin(); |
|---|
| 224 |
j != this->Commands.end(); ++j) |
|---|
| 225 |
{ |
|---|
| 226 |
delete (*j).second; |
|---|
| 227 |
} |
|---|
| 228 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 229 |
delete this->VariableWatch; |
|---|
| 230 |
#endif |
|---|
| 231 |
delete this->FileComparison; |
|---|
| 232 |
} |
|---|
| 233 |
|
|---|
| 234 |
void cmake::InitializeProperties() |
|---|
| 235 |
{ |
|---|
| 236 |
this->Properties.clear(); |
|---|
| 237 |
this->Properties.SetCMakeInstance(this); |
|---|
| 238 |
this->AccessedProperties.clear(); |
|---|
| 239 |
this->PropertyDefinitions.clear(); |
|---|
| 240 |
|
|---|
| 241 |
// initialize properties |
|---|
| 242 |
cmCacheManager::DefineProperties(this); |
|---|
| 243 |
cmSourceFile::DefineProperties(this); |
|---|
| 244 |
cmTarget::DefineProperties(this); |
|---|
| 245 |
cmMakefile::DefineProperties(this); |
|---|
| 246 |
cmTest::DefineProperties(this); |
|---|
| 247 |
cmake::DefineProperties(this); |
|---|
| 248 |
} |
|---|
| 249 |
|
|---|
| 250 |
void cmake::CleanupCommandsAndMacros() |
|---|
| 251 |
{ |
|---|
| 252 |
this->InitializeProperties(); |
|---|
| 253 |
std::vector<cmCommand*> commands; |
|---|
| 254 |
for(RegisteredCommandsMap::iterator j = this->Commands.begin(); |
|---|
| 255 |
j != this->Commands.end(); ++j) |
|---|
| 256 |
{ |
|---|
| 257 |
if ( !j->second->IsA("cmMacroHelperCommand") && |
|---|
| 258 |
!j->second->IsA("cmFunctionHelperCommand")) |
|---|
| 259 |
{ |
|---|
| 260 |
commands.push_back(j->second); |
|---|
| 261 |
} |
|---|
| 262 |
else |
|---|
| 263 |
{ |
|---|
| 264 |
delete j->second; |
|---|
| 265 |
} |
|---|
| 266 |
} |
|---|
| 267 |
this->Commands.erase(this->Commands.begin(), this->Commands.end()); |
|---|
| 268 |
std::vector<cmCommand*>::iterator it; |
|---|
| 269 |
for ( it = commands.begin(); it != commands.end(); |
|---|
| 270 |
++ it ) |
|---|
| 271 |
{ |
|---|
| 272 |
this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it; |
|---|
| 273 |
} |
|---|
| 274 |
} |
|---|
| 275 |
|
|---|
| 276 |
bool cmake::CommandExists(const char* name) const |
|---|
| 277 |
{ |
|---|
| 278 |
std::string sName = cmSystemTools::LowerCase(name); |
|---|
| 279 |
return (this->Commands.find(sName) != this->Commands.end()); |
|---|
| 280 |
} |
|---|
| 281 |
|
|---|
| 282 |
cmCommand *cmake::GetCommand(const char *name) |
|---|
| 283 |
{ |
|---|
| 284 |
cmCommand* rm = 0; |
|---|
| 285 |
std::string sName = cmSystemTools::LowerCase(name); |
|---|
| 286 |
RegisteredCommandsMap::iterator pos = this->Commands.find(sName); |
|---|
| 287 |
if (pos != this->Commands.end()) |
|---|
| 288 |
{ |
|---|
| 289 |
rm = (*pos).second; |
|---|
| 290 |
} |
|---|
| 291 |
return rm; |
|---|
| 292 |
} |
|---|
| 293 |
|
|---|
| 294 |
void cmake::RenameCommand(const char*oldName, const char* newName) |
|---|
| 295 |
{ |
|---|
| 296 |
// if the command already exists, free the old one |
|---|
| 297 |
std::string sOldName = cmSystemTools::LowerCase(oldName); |
|---|
| 298 |
std::string sNewName = cmSystemTools::LowerCase(newName); |
|---|
| 299 |
RegisteredCommandsMap::iterator pos = this->Commands.find(sOldName); |
|---|
| 300 |
if ( pos == this->Commands.end() ) |
|---|
| 301 |
{ |
|---|
| 302 |
return; |
|---|
| 303 |
} |
|---|
| 304 |
cmCommand* cmd = pos->second; |
|---|
| 305 |
|
|---|
| 306 |
pos = this->Commands.find(sNewName); |
|---|
| 307 |
if (pos != this->Commands.end()) |
|---|
| 308 |
{ |
|---|
| 309 |
delete pos->second; |
|---|
| 310 |
this->Commands.erase(pos); |
|---|
| 311 |
} |
|---|
| 312 |
this->Commands.insert(RegisteredCommandsMap::value_type(sNewName, cmd)); |
|---|
| 313 |
pos = this->Commands.find(sOldName); |
|---|
| 314 |
this->Commands.erase(pos); |
|---|
| 315 |
} |
|---|
| 316 |
|
|---|
| 317 |
void cmake::RemoveCommand(const char* name) |
|---|
| 318 |
{ |
|---|
| 319 |
std::string sName = cmSystemTools::LowerCase(name); |
|---|
| 320 |
RegisteredCommandsMap::iterator pos = this->Commands.find(sName); |
|---|
| 321 |
if ( pos != this->Commands.end() ) |
|---|
| 322 |
{ |
|---|
| 323 |
delete pos->second; |
|---|
| 324 |
this->Commands.erase(pos); |
|---|
| 325 |
} |
|---|
| 326 |
} |
|---|
| 327 |
|
|---|
| 328 |
void cmake::AddCommand(cmCommand* wg) |
|---|
| 329 |
{ |
|---|
| 330 |
std::string name = cmSystemTools::LowerCase(wg->GetName()); |
|---|
| 331 |
// if the command already exists, free the old one |
|---|
| 332 |
RegisteredCommandsMap::iterator pos = this->Commands.find(name); |
|---|
| 333 |
if (pos != this->Commands.end()) |
|---|
| 334 |
{ |
|---|
| 335 |
delete pos->second; |
|---|
| 336 |
this->Commands.erase(pos); |
|---|
| 337 |
} |
|---|
| 338 |
this->Commands.insert( RegisteredCommandsMap::value_type(name, wg)); |
|---|
| 339 |
} |
|---|
| 340 |
|
|---|
| 341 |
|
|---|
| 342 |
void cmake::RemoveUnscriptableCommands() |
|---|
| 343 |
{ |
|---|
| 344 |
std::vector<std::string> unscriptableCommands; |
|---|
| 345 |
cmake::RegisteredCommandsMap* commands = this->GetCommands(); |
|---|
| 346 |
for (cmake::RegisteredCommandsMap::const_iterator pos = commands->begin(); |
|---|
| 347 |
pos != commands->end(); |
|---|
| 348 |
++pos) |
|---|
| 349 |
{ |
|---|
| 350 |
if (!pos->second->IsScriptable()) |
|---|
| 351 |
{ |
|---|
| 352 |
unscriptableCommands.push_back(pos->first); |
|---|
| 353 |
} |
|---|
| 354 |
} |
|---|
| 355 |
|
|---|
| 356 |
for(std::vector<std::string>::const_iterator it=unscriptableCommands.begin(); |
|---|
| 357 |
it != unscriptableCommands.end(); |
|---|
| 358 |
++it) |
|---|
| 359 |
{ |
|---|
| 360 |
this->RemoveCommand(it->c_str()); |
|---|
| 361 |
} |
|---|
| 362 |
} |
|---|
| 363 |
|
|---|
| 364 |
// Parse the args |
|---|
| 365 |
bool cmake::SetCacheArgs(const std::vector<std::string>& args) |
|---|
| 366 |
{ |
|---|
| 367 |
for(unsigned int i=1; i < args.size(); ++i) |
|---|
| 368 |
{ |
|---|
| 369 |
std::string arg = args[i]; |
|---|
| 370 |
if(arg.find("-D",0) == 0) |
|---|
| 371 |
{ |
|---|
| 372 |
std::string entry = arg.substr(2); |
|---|
| 373 |
if(entry.size() == 0) |
|---|
| 374 |
{ |
|---|
| 375 |
++i; |
|---|
| 376 |
if(i < args.size()) |
|---|
| 377 |
{ |
|---|
| 378 |
entry = args[i]; |
|---|
| 379 |
} |
|---|
| 380 |
else |
|---|
| 381 |
{ |
|---|
| 382 |
cmSystemTools::Error("-D must be followed with VAR=VALUE."); |
|---|
| 383 |
return false; |
|---|
| 384 |
} |
|---|
| 385 |
} |
|---|
| 386 |
std::string var, value; |
|---|
| 387 |
cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; |
|---|
| 388 |
if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type) || |
|---|
| 389 |
cmCacheManager::ParseEntry(entry.c_str(), var, value)) |
|---|
| 390 |
{ |
|---|
| 391 |
this->CacheManager->AddCacheEntry(var.c_str(), value.c_str(), |
|---|
| 392 |
"No help, variable specified on the command line.", type); |
|---|
| 393 |
} |
|---|
| 394 |
else |
|---|
| 395 |
{ |
|---|
| 396 |
std::cerr << "Parse error in command line argument: " << arg << "\n" |
|---|
| 397 |
<< "Should be: VAR:type=value\n"; |
|---|
| 398 |
cmSystemTools::Error("No cmake script provided."); |
|---|
| 399 |
return false; |
|---|
| 400 |
} |
|---|
| 401 |
} |
|---|
| 402 |
else if(arg.find("-Wno-dev",0) == 0) |
|---|
| 403 |
{ |
|---|
| 404 |
this->SuppressDevWarnings = true; |
|---|
| 405 |
this->DoSuppressDevWarnings = true; |
|---|
| 406 |
} |
|---|
| 407 |
else if(arg.find("-Wdev",0) == 0) |
|---|
| 408 |
{ |
|---|
| 409 |
this->SuppressDevWarnings = false; |
|---|
| 410 |
this->DoSuppressDevWarnings = true; |
|---|
| 411 |
} |
|---|
| 412 |
else if(arg.find("-U",0) == 0) |
|---|
| 413 |
{ |
|---|
| 414 |
std::string entryPattern = arg.substr(2); |
|---|
| 415 |
if(entryPattern.size() == 0) |
|---|
| 416 |
{ |
|---|
| 417 |
++i; |
|---|
| 418 |
if(i < args.size()) |
|---|
| 419 |
{ |
|---|
| 420 |
entryPattern = args[i]; |
|---|
| 421 |
} |
|---|
| 422 |
else |
|---|
| 423 |
{ |
|---|
| 424 |
cmSystemTools::Error("-U must be followed with VAR."); |
|---|
| 425 |
return false; |
|---|
| 426 |
} |
|---|
| 427 |
} |
|---|
| 428 |
cmsys::RegularExpression regex( |
|---|
| 429 |
cmsys::Glob::PatternToRegex(entryPattern.c_str(), true, true).c_str()); |
|---|
| 430 |
//go through all cache entries and collect the vars which will be removed |
|---|
| 431 |
std::vector<std::string> entriesToDelete; |
|---|
| 432 |
cmCacheManager::CacheIterator it = |
|---|
| 433 |
this->CacheManager->GetCacheIterator(); |
|---|
| 434 |
for ( it.Begin(); !it.IsAtEnd(); it.Next() ) |
|---|
| 435 |
{ |
|---|
| 436 |
cmCacheManager::CacheEntryType t = it.GetType(); |
|---|
| 437 |
if(t != cmCacheManager::STATIC) |
|---|
| 438 |
{ |
|---|
| 439 |
std::string entryName = it.GetName(); |
|---|
| 440 |
if (regex.find(entryName.c_str())) |
|---|
| 441 |
{ |
|---|
| 442 |
entriesToDelete.push_back(entryName); |
|---|
| 443 |
} |
|---|
| 444 |
} |
|---|
| 445 |
} |
|---|
| 446 |
|
|---|
| 447 |
// now remove them from the cache |
|---|
| 448 |
for(std::vector<std::string>::const_iterator currentEntry = |
|---|
| 449 |
entriesToDelete.begin(); |
|---|
| 450 |
currentEntry != entriesToDelete.end(); |
|---|
| 451 |
++currentEntry) |
|---|
| 452 |
{ |
|---|
| 453 |
this->CacheManager->RemoveCacheEntry(currentEntry->c_str()); |
|---|
| 454 |
} |
|---|
| 455 |
} |
|---|
| 456 |
else if(arg.find("-C",0) == 0) |
|---|
| 457 |
{ |
|---|
| 458 |
std::string path = arg.substr(2); |
|---|
| 459 |
if ( path.size() == 0 ) |
|---|
| 460 |
{ |
|---|
| 461 |
++i; |
|---|
| 462 |
if(i < args.size()) |
|---|
| 463 |
{ |
|---|
| 464 |
path = args[i]; |
|---|
| 465 |
} |
|---|
| 466 |
else |
|---|
| 467 |
{ |
|---|
| 468 |
cmSystemTools::Error("-C must be followed by a file name."); |
|---|
| 469 |
return false; |
|---|
| 470 |
} |
|---|
| 471 |
} |
|---|
| 472 |
std::cerr << "loading initial cache file " << path.c_str() << "\n"; |
|---|
| 473 |
this->ReadListFile(path.c_str()); |
|---|
| 474 |
} |
|---|
| 475 |
else if(arg.find("-P",0) == 0) |
|---|
| 476 |
{ |
|---|
| 477 |
i++; |
|---|
| 478 |
if(i >= args.size()) |
|---|
| 479 |
{ |
|---|
| 480 |
cmSystemTools::Error("-P must be followed by a file name."); |
|---|
| 481 |
return false; |
|---|
| 482 |
} |
|---|
| 483 |
std::string path = args[i]; |
|---|
| 484 |
if ( path.size() == 0 ) |
|---|
| 485 |
{ |
|---|
| 486 |
cmSystemTools::Error("No cmake script provided."); |
|---|
| 487 |
return false; |
|---|
| 488 |
} |
|---|
| 489 |
this->ReadListFile(path.c_str()); |
|---|
| 490 |
} |
|---|
| 491 |
} |
|---|
| 492 |
return true; |
|---|
| 493 |
} |
|---|
| 494 |
|
|---|
| 495 |
void cmake::ReadListFile(const char *path) |
|---|
| 496 |
{ |
|---|
| 497 |
// if a generator was not yet created, temporarily create one |
|---|
| 498 |
cmGlobalGenerator *gg = this->GetGlobalGenerator(); |
|---|
| 499 |
bool created = false; |
|---|
| 500 |
|
|---|
| 501 |
// if a generator was not specified use a generic one |
|---|
| 502 |
if (!gg) |
|---|
| 503 |
{ |
|---|
| 504 |
gg = new cmGlobalGenerator; |
|---|
| 505 |
gg->SetCMakeInstance(this); |
|---|
| 506 |
created = true; |
|---|
| 507 |
} |
|---|
| 508 |
|
|---|
| 509 |
// read in the list file to fill the cache |
|---|
| 510 |
if(path) |
|---|
| 511 |
{ |
|---|
| 512 |
std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator()); |
|---|
| 513 |
lg->GetMakefile()->SetHomeOutputDirectory |
|---|
| 514 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 515 |
lg->GetMakefile()->SetStartOutputDirectory |
|---|
| 516 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 517 |
lg->GetMakefile()->SetHomeDirectory |
|---|
| 518 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 519 |
lg->GetMakefile()->SetStartDirectory |
|---|
| 520 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 521 |
if (!lg->GetMakefile()->ReadListFile(0, path)) |
|---|
| 522 |
{ |
|---|
| 523 |
cmSystemTools::Error("Error processing file:", path); |
|---|
| 524 |
} |
|---|
| 525 |
} |
|---|
| 526 |
|
|---|
| 527 |
// free generic one if generated |
|---|
| 528 |
if (created) |
|---|
| 529 |
{ |
|---|
| 530 |
delete gg; |
|---|
| 531 |
} |
|---|
| 532 |
} |
|---|
| 533 |
|
|---|
| 534 |
// Parse the args |
|---|
| 535 |
void cmake::SetArgs(const std::vector<std::string>& args) |
|---|
| 536 |
{ |
|---|
| 537 |
bool directoriesSet = false; |
|---|
| 538 |
for(unsigned int i=1; i < args.size(); ++i) |
|---|
| 539 |
{ |
|---|
| 540 |
std::string arg = args[i]; |
|---|
| 541 |
if(arg.find("-H",0) == 0) |
|---|
| 542 |
{ |
|---|
| 543 |
directoriesSet = true; |
|---|
| 544 |
std::string path = arg.substr(2); |
|---|
| 545 |
path = cmSystemTools::CollapseFullPath(path.c_str()); |
|---|
| 546 |
cmSystemTools::ConvertToUnixSlashes(path); |
|---|
| 547 |
this->SetHomeDirectory(path.c_str()); |
|---|
| 548 |
} |
|---|
| 549 |
else if(arg.find("-S",0) == 0) |
|---|
| 550 |
{ |
|---|
| 551 |
// There is no local generate anymore. Ignore -S option. |
|---|
| 552 |
} |
|---|
| 553 |
else if(arg.find("-O",0) == 0) |
|---|
| 554 |
{ |
|---|
| 555 |
// There is no local generate anymore. Ignore -O option. |
|---|
| 556 |
} |
|---|
| 557 |
else if(arg.find("-B",0) == 0) |
|---|
| 558 |
{ |
|---|
| 559 |
directoriesSet = true; |
|---|
| 560 |
std::string path = arg.substr(2); |
|---|
| 561 |
path = cmSystemTools::CollapseFullPath(path.c_str()); |
|---|
| 562 |
cmSystemTools::ConvertToUnixSlashes(path); |
|---|
| 563 |
this->SetHomeOutputDirectory(path.c_str()); |
|---|
| 564 |
} |
|---|
| 565 |
else if((i < args.size()-1) && (arg.find("--check-build-system",0) == 0)) |
|---|
| 566 |
{ |
|---|
| 567 |
this->CheckBuildSystemArgument = args[++i]; |
|---|
| 568 |
this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0); |
|---|
| 569 |
} |
|---|
| 570 |
else if((i < args.size()-1) && (arg.find("--check-stamp-file",0) == 0)) |
|---|
| 571 |
{ |
|---|
| 572 |
this->CheckStampFile = args[++i]; |
|---|
| 573 |
} |
|---|
| 574 |
else if((i < args.size()-1) && (arg.find("--check-stamp-list",0) == 0)) |
|---|
| 575 |
{ |
|---|
| 576 |
this->CheckStampList = args[++i]; |
|---|
| 577 |
} |
|---|
| 578 |
#if defined(CMAKE_HAVE_VS_GENERATORS) |
|---|
| 579 |
else if((i < args.size()-1) && (arg.find("--vs-solution-file",0) == 0)) |
|---|
| 580 |
{ |
|---|
| 581 |
this->VSSolutionFile = args[++i]; |
|---|
| 582 |
} |
|---|
| 583 |
#endif |
|---|
| 584 |
else if(arg.find("-V",0) == 0) |
|---|
| 585 |
{ |
|---|
| 586 |
this->Verbose = true; |
|---|
| 587 |
} |
|---|
| 588 |
else if(arg.find("-D",0) == 0) |
|---|
| 589 |
{ |
|---|
| 590 |
// skip for now |
|---|
| 591 |
} |
|---|
| 592 |
else if(arg.find("-U",0) == 0) |
|---|
| 593 |
{ |
|---|
| 594 |
// skip for now |
|---|
| 595 |
} |
|---|
| 596 |
else if(arg.find("-C",0) == 0) |
|---|
| 597 |
{ |
|---|
| 598 |
// skip for now |
|---|
| 599 |
} |
|---|
| 600 |
else if(arg.find("-P",0) == 0) |
|---|
| 601 |
{ |
|---|
| 602 |
// skip for now |
|---|
| 603 |
i++; |
|---|
| 604 |
} |
|---|
| 605 |
else if(arg.find("-Wno-dev",0) == 0) |
|---|
| 606 |
{ |
|---|
| 607 |
// skip for now |
|---|
| 608 |
} |
|---|
| 609 |
else if(arg.find("-Wdev",0) == 0) |
|---|
| 610 |
{ |
|---|
| 611 |
// skip for now |
|---|
| 612 |
} |
|---|
| 613 |
else if(arg.find("--graphviz=",0) == 0) |
|---|
| 614 |
{ |
|---|
| 615 |
std::string path = arg.substr(strlen("--graphviz=")); |
|---|
| 616 |
path = cmSystemTools::CollapseFullPath(path.c_str()); |
|---|
| 617 |
cmSystemTools::ConvertToUnixSlashes(path); |
|---|
| 618 |
this->GraphVizFile = path; |
|---|
| 619 |
if ( this->GraphVizFile.empty() ) |
|---|
| 620 |
{ |
|---|
| 621 |
cmSystemTools::Error("No file specified for --graphviz"); |
|---|
| 622 |
} |
|---|
| 623 |
} |
|---|
| 624 |
else if(arg.find("--debug-trycompile",0) == 0) |
|---|
| 625 |
{ |
|---|
| 626 |
std::cout << "debug trycompile on\n"; |
|---|
| 627 |
this->DebugTryCompileOn(); |
|---|
| 628 |
} |
|---|
| 629 |
else if(arg.find("--debug-output",0) == 0) |
|---|
| 630 |
{ |
|---|
| 631 |
std::cout << "Running with debug output on.\n"; |
|---|
| 632 |
this->SetDebugOutputOn(true); |
|---|
| 633 |
} |
|---|
| 634 |
else if(arg.find("--trace",0) == 0) |
|---|
| 635 |
{ |
|---|
| 636 |
std::cout << "Running with trace output on.\n"; |
|---|
| 637 |
this->SetTrace(true); |
|---|
| 638 |
} |
|---|
| 639 |
else if(arg.find("-G",0) == 0) |
|---|
| 640 |
{ |
|---|
| 641 |
std::string value = arg.substr(2); |
|---|
| 642 |
if(value.size() == 0) |
|---|
| 643 |
{ |
|---|
| 644 |
++i; |
|---|
| 645 |
if(i >= args.size()) |
|---|
| 646 |
{ |
|---|
| 647 |
cmSystemTools::Error("No generator specified for -G"); |
|---|
| 648 |
return; |
|---|
| 649 |
} |
|---|
| 650 |
value = args[i]; |
|---|
| 651 |
} |
|---|
| 652 |
cmGlobalGenerator* gen = |
|---|
| 653 |
this->CreateGlobalGenerator(value.c_str()); |
|---|
| 654 |
if(!gen) |
|---|
| 655 |
{ |
|---|
| 656 |
cmSystemTools::Error("Could not create named generator ", |
|---|
| 657 |
value.c_str()); |
|---|
| 658 |
} |
|---|
| 659 |
else |
|---|
| 660 |
{ |
|---|
| 661 |
this->SetGlobalGenerator(gen); |
|---|
| 662 |
} |
|---|
| 663 |
} |
|---|
| 664 |
// no option assume it is the path to the source |
|---|
| 665 |
else |
|---|
| 666 |
{ |
|---|
| 667 |
directoriesSet = true; |
|---|
| 668 |
this->SetDirectoriesFromFile(arg.c_str()); |
|---|
| 669 |
} |
|---|
| 670 |
} |
|---|
| 671 |
if(!directoriesSet) |
|---|
| 672 |
{ |
|---|
| 673 |
this->SetHomeOutputDirectory |
|---|
| 674 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 675 |
this->SetStartOutputDirectory |
|---|
| 676 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 677 |
this->SetHomeDirectory |
|---|
| 678 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 679 |
this->SetStartDirectory |
|---|
| 680 |
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); |
|---|
| 681 |
} |
|---|
| 682 |
|
|---|
| 683 |
this->SetStartDirectory(this->GetHomeDirectory()); |
|---|
| 684 |
this->SetStartOutputDirectory(this->GetHomeOutputDirectory()); |
|---|
| 685 |
} |
|---|
| 686 |
|
|---|
| 687 |
//---------------------------------------------------------------------------- |
|---|
| 688 |
void cmake::SetDirectoriesFromFile(const char* arg) |
|---|
| 689 |
{ |
|---|
| 690 |
// Check if the argument refers to a CMakeCache.txt or |
|---|
| 691 |
// CMakeLists.txt file. |
|---|
| 692 |
std::string listPath; |
|---|
| 693 |
std::string cachePath; |
|---|
| 694 |
bool argIsFile = false; |
|---|
| 695 |
if(cmSystemTools::FileIsDirectory(arg)) |
|---|
| 696 |
{ |
|---|
| 697 |
std::string path = cmSystemTools::CollapseFullPath(arg); |
|---|
| 698 |
cmSystemTools::ConvertToUnixSlashes(path); |
|---|
| 699 |
std::string cacheFile = path; |
|---|
| 700 |
cacheFile += "/CMakeCache.txt"; |
|---|
| 701 |
std::string listFile = path; |
|---|
| 702 |
listFile += "/CMakeLists.txt"; |
|---|
| 703 |
if(cmSystemTools::FileExists(cacheFile.c_str())) |
|---|
| 704 |
{ |
|---|
| 705 |
cachePath = path; |
|---|
| 706 |
} |
|---|
| 707 |
if(cmSystemTools::FileExists(listFile.c_str())) |
|---|
| 708 |
{ |
|---|
| 709 |
listPath = path; |
|---|
| 710 |
} |
|---|
| 711 |
} |
|---|
| 712 |
else if(cmSystemTools::FileExists(arg)) |
|---|
| 713 |
{ |
|---|
| 714 |
argIsFile = true; |
|---|
| 715 |
std::string fullPath = cmSystemTools::CollapseFullPath(arg); |
|---|
| 716 |
std::string name = cmSystemTools::GetFilenameName(fullPath.c_str()); |
|---|
| 717 |
name = cmSystemTools::LowerCase(name); |
|---|
| 718 |
if(name == "cmakecache.txt") |
|---|
| 719 |
{ |
|---|
| 720 |
cachePath = cmSystemTools::GetFilenamePath(fullPath.c_str()); |
|---|
| 721 |
} |
|---|
| 722 |
else if(name == "cmakelists.txt") |
|---|
| 723 |
{ |
|---|
| 724 |
listPath = cmSystemTools::GetFilenamePath(fullPath.c_str()); |
|---|
| 725 |
} |
|---|
| 726 |
} |
|---|
| 727 |
else |
|---|
| 728 |
{ |
|---|
| 729 |
// Specified file or directory does not exist. Try to set things |
|---|
| 730 |
// up to produce a meaningful error message. |
|---|
| 731 |
std::string fullPath = cmSystemTools::CollapseFullPath(arg); |
|---|
| 732 |
std::string name = cmSystemTools::GetFilenameName(fullPath.c_str()); |
|---|
| 733 |
name = cmSystemTools::LowerCase(name); |
|---|
| 734 |
if(name == "cmakecache.txt" || name == "cmakelists.txt") |
|---|
| 735 |
{ |
|---|
| 736 |
argIsFile = true; |
|---|
| 737 |
listPath = cmSystemTools::GetFilenamePath(fullPath.c_str()); |
|---|
| 738 |
} |
|---|
| 739 |
else |
|---|
| 740 |
{ |
|---|
| 741 |
listPath = fullPath; |
|---|
| 742 |
} |
|---|
| 743 |
} |
|---|
| 744 |
|
|---|
| 745 |
// If there is a CMakeCache.txt file, use its settings. |
|---|
| 746 |
if(cachePath.length() > 0) |
|---|
| 747 |
{ |
|---|
| 748 |
cmCacheManager* cachem = this->GetCacheManager(); |
|---|
| 749 |
cmCacheManager::CacheIterator it = cachem->NewIterator(); |
|---|
| 750 |
if(cachem->LoadCache(cachePath.c_str()) && |
|---|
| 751 |
it.Find("CMAKE_HOME_DIRECTORY")) |
|---|
| 752 |
{ |
|---|
| 753 |
this->SetHomeOutputDirectory(cachePath.c_str()); |
|---|
| 754 |
this->SetStartOutputDirectory(cachePath.c_str()); |
|---|
| 755 |
this->SetHomeDirectory(it.GetValue()); |
|---|
| 756 |
this->SetStartDirectory(it.GetValue()); |
|---|
| 757 |
return; |
|---|
| 758 |
} |
|---|
| 759 |
} |
|---|
| 760 |
|
|---|
| 761 |
// If there is a CMakeLists.txt file, use it as the source tree. |
|---|
| 762 |
if(listPath.length() > 0) |
|---|
| 763 |
{ |
|---|
| 764 |
this->SetHomeDirectory(listPath.c_str()); |
|---|
| 765 |
this->SetStartDirectory(listPath.c_str()); |
|---|
| 766 |
|
|---|
| 767 |
if(argIsFile) |
|---|
| 768 |
{ |
|---|
| 769 |
// Source CMakeLists.txt file given. It was probably dropped |
|---|
| 770 |
// onto the executable in a GUI. Default to an in-source build. |
|---|
| 771 |
this->SetHomeOutputDirectory(listPath.c_str()); |
|---|
| 772 |
this->SetStartOutputDirectory(listPath.c_str()); |
|---|
| 773 |
} |
|---|
| 774 |
else |
|---|
| 775 |
{ |
|---|
| 776 |
// Source directory given on command line. Use current working |
|---|
| 777 |
// directory as build tree. |
|---|
| 778 |
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); |
|---|
| 779 |
this->SetHomeOutputDirectory(cwd.c_str()); |
|---|
| 780 |
this->SetStartOutputDirectory(cwd.c_str()); |
|---|
| 781 |
} |
|---|
| 782 |
return; |
|---|
| 783 |
} |
|---|
| 784 |
|
|---|
| 785 |
// We didn't find a CMakeLists.txt or CMakeCache.txt file from the |
|---|
| 786 |
// argument. Assume it is the path to the source tree, and use the |
|---|
| 787 |
// current working directory as the build tree. |
|---|
| 788 |
std::string full = cmSystemTools::CollapseFullPath(arg); |
|---|
| 789 |
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); |
|---|
| 790 |
this->SetHomeDirectory(full.c_str()); |
|---|
| 791 |
this->SetStartDirectory(full.c_str()); |
|---|
| 792 |
this->SetHomeOutputDirectory(cwd.c_str()); |
|---|
| 793 |
this->SetStartOutputDirectory(cwd.c_str()); |
|---|
| 794 |
} |
|---|
| 795 |
|
|---|
| 796 |
// at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the |
|---|
| 797 |
// cache |
|---|
| 798 |
int cmake::AddCMakePaths() |
|---|
| 799 |
{ |
|---|
| 800 |
// Find the cmake executable |
|---|
| 801 |
std::string cMakeSelf = cmSystemTools::GetExecutableDirectory(); |
|---|
| 802 |
cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); |
|---|
| 803 |
cMakeSelf += "/cmake"; |
|---|
| 804 |
cMakeSelf += cmSystemTools::GetExecutableExtension(); |
|---|
| 805 |
#if __APPLE__ |
|---|
| 806 |
// on the apple this might be the gui bundle |
|---|
| 807 |
if(!cmSystemTools::FileExists(cMakeSelf.c_str())) |
|---|
| 808 |
{ |
|---|
| 809 |
cMakeSelf = cmSystemTools::GetExecutableDirectory(); |
|---|
| 810 |
cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); |
|---|
| 811 |
cMakeSelf += "../../../.."; |
|---|
| 812 |
cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); |
|---|
| 813 |
cMakeSelf = cmSystemTools::CollapseFullPath(cMakeSelf.c_str()); |
|---|
| 814 |
cMakeSelf += "/cmake"; |
|---|
| 815 |
std::cerr << cMakeSelf.c_str() << "\n"; |
|---|
| 816 |
} |
|---|
| 817 |
#endif |
|---|
| 818 |
if(!cmSystemTools::FileExists(cMakeSelf.c_str())) |
|---|
| 819 |
{ |
|---|
| 820 |
cmSystemTools::Error("CMake executable cannot be found at ", |
|---|
| 821 |
cMakeSelf.c_str()); |
|---|
| 822 |
return 0; |
|---|
| 823 |
} |
|---|
| 824 |
// Save the value in the cache |
|---|
| 825 |
this->CacheManager->AddCacheEntry |
|---|
| 826 |
("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.", |
|---|
| 827 |
cmCacheManager::INTERNAL); |
|---|
| 828 |
// if the edit command is not yet in the cache, |
|---|
| 829 |
// or if CMakeEditCommand has been set on this object, |
|---|
| 830 |
// then set the CMAKE_EDIT_COMMAND in the cache |
|---|
| 831 |
// This will mean that the last gui to edit the cache |
|---|
| 832 |
// will be the one that make edit_cache uses. |
|---|
| 833 |
if(!this->GetCacheDefinition("CMAKE_EDIT_COMMAND") |
|---|
| 834 |
|| !this->CMakeEditCommand.empty()) |
|---|
| 835 |
{ |
|---|
| 836 |
// Find and save the command to edit the cache |
|---|
| 837 |
std::string editCacheCommand; |
|---|
| 838 |
if(!this->CMakeEditCommand.empty()) |
|---|
| 839 |
{ |
|---|
| 840 |
editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) |
|---|
| 841 |
+ std::string("/") |
|---|
| 842 |
+ this->CMakeEditCommand |
|---|
| 843 |
+ cmSystemTools::GetFilenameExtension(cMakeSelf); |
|---|
| 844 |
} |
|---|
| 845 |
if( !cmSystemTools::FileExists(editCacheCommand.c_str())) |
|---|
| 846 |
{ |
|---|
| 847 |
editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) + |
|---|
| 848 |
"/ccmake" + cmSystemTools::GetFilenameExtension(cMakeSelf); |
|---|
| 849 |
} |
|---|
| 850 |
if( !cmSystemTools::FileExists(editCacheCommand.c_str())) |
|---|
| 851 |
{ |
|---|
| 852 |
editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) + |
|---|
| 853 |
"/cmake-gui" + cmSystemTools::GetFilenameExtension(cMakeSelf); |
|---|
| 854 |
} |
|---|
| 855 |
if(cmSystemTools::FileExists(editCacheCommand.c_str())) |
|---|
| 856 |
{ |
|---|
| 857 |
this->CacheManager->AddCacheEntry |
|---|
| 858 |
("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(), |
|---|
| 859 |
"Path to cache edit program executable.", cmCacheManager::INTERNAL); |
|---|
| 860 |
} |
|---|
| 861 |
} |
|---|
| 862 |
std::string ctestCommand = cmSystemTools::GetFilenamePath(cMakeSelf) + |
|---|
| 863 |
"/ctest" + cmSystemTools::GetFilenameExtension(cMakeSelf); |
|---|
| 864 |
if(cmSystemTools::FileExists(ctestCommand.c_str())) |
|---|
| 865 |
{ |
|---|
| 866 |
this->CacheManager->AddCacheEntry |
|---|
| 867 |
("CMAKE_CTEST_COMMAND", ctestCommand.c_str(), |
|---|
| 868 |
"Path to ctest program executable.", cmCacheManager::INTERNAL); |
|---|
| 869 |
} |
|---|
| 870 |
std::string cpackCommand = cmSystemTools::GetFilenamePath(cMakeSelf) + |
|---|
| 871 |
"/cpack" + cmSystemTools::GetFilenameExtension(cMakeSelf); |
|---|
| 872 |
if(cmSystemTools::FileExists(cpackCommand.c_str())) |
|---|
| 873 |
{ |
|---|
| 874 |
this->CacheManager->AddCacheEntry |
|---|
| 875 |
("CMAKE_CPACK_COMMAND", cpackCommand.c_str(), |
|---|
| 876 |
"Path to cpack program executable.", cmCacheManager::INTERNAL); |
|---|
| 877 |
} |
|---|
| 878 |
|
|---|
| 879 |
// do CMAKE_ROOT, look for the environment variable first |
|---|
| 880 |
std::string cMakeRoot; |
|---|
| 881 |
std::string modules; |
|---|
| 882 |
if (getenv("CMAKE_ROOT")) |
|---|
| 883 |
{ |
|---|
| 884 |
cMakeRoot = getenv("CMAKE_ROOT"); |
|---|
| 885 |
modules = cMakeRoot + "/Modules/CMake.cmake"; |
|---|
| 886 |
} |
|---|
| 887 |
if(!cmSystemTools::FileExists(modules.c_str())) |
|---|
| 888 |
{ |
|---|
| 889 |
// next try exe/.. |
|---|
| 890 |
cMakeRoot = cmSystemTools::GetRealPath(cMakeSelf.c_str()); |
|---|
| 891 |
cMakeRoot = cmSystemTools::GetProgramPath(cMakeRoot.c_str()); |
|---|
| 892 |
std::string::size_type slashPos = cMakeRoot.rfind("/"); |
|---|
| 893 |
if(slashPos != std::string::npos) |
|---|
| 894 |
{ |
|---|
| 895 |
cMakeRoot = cMakeRoot.substr(0, slashPos); |
|---|
| 896 |
} |
|---|
| 897 |
// is there no Modules direcory there? |
|---|
| 898 |
modules = cMakeRoot + "/Modules/CMake.cmake"; |
|---|
| 899 |
} |
|---|
| 900 |
|
|---|
| 901 |
if (!cmSystemTools::FileExists(modules.c_str())) |
|---|
| 902 |
{ |
|---|
| 903 |
// try exe/../share/cmake |
|---|
| 904 |
cMakeRoot += CMAKE_DATA_DIR; |
|---|
| 905 |
modules = cMakeRoot + "/Modules/CMake.cmake"; |
|---|
| 906 |
} |
|---|
| 907 |
#ifdef CMAKE_ROOT_DIR |
|---|
| 908 |
if (!cmSystemTools::FileExists(modules.c_str())) |
|---|
| 909 |
{ |
|---|
| 910 |
// try compiled in root directory |
|---|
| 911 |
cMakeRoot = CMAKE_ROOT_DIR; |
|---|
| 912 |
modules = cMakeRoot + "/Modules/CMake.cmake"; |
|---|
| 913 |
} |
|---|
| 914 |
#endif |
|---|
| 915 |
if (!cmSystemTools::FileExists(modules.c_str())) |
|---|
| 916 |
{ |
|---|
| 917 |
// try |
|---|
| 918 |
cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str()); |
|---|
| 919 |
cMakeRoot += CMAKE_DATA_DIR; |
|---|
| 920 |
modules = cMakeRoot + "/Modules/CMake.cmake"; |
|---|
| 921 |
} |
|---|
| 922 |
if(!cmSystemTools::FileExists(modules.c_str())) |
|---|
| 923 |
{ |
|---|
| 924 |
// next try exe |
|---|
| 925 |
cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str()); |
|---|
| 926 |
// is there no Modules direcory there? |
|---|
| 927 |
modules = cMakeRoot + "/Modules/CMake.cmake"; |
|---|
| 928 |
} |
|---|
| 929 |
if (!cmSystemTools::FileExists(modules.c_str())) |
|---|
| 930 |
{ |
|---|
| 931 |
// couldn't find modules |
|---|
| 932 |
cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n" |
|---|
| 933 |
"CMake has most likely not been installed correctly.\n" |
|---|
| 934 |
"Modules directory not found in\n", |
|---|
| 935 |
cMakeRoot.c_str()); |
|---|
| 936 |
return 0; |
|---|
| 937 |
} |
|---|
| 938 |
this->CacheManager->AddCacheEntry |
|---|
| 939 |
("CMAKE_ROOT", cMakeRoot.c_str(), |
|---|
| 940 |
"Path to CMake installation.", cmCacheManager::INTERNAL); |
|---|
| 941 |
|
|---|
| 942 |
#ifdef _WIN32 |
|---|
| 943 |
std::string comspec = "cmw9xcom.exe"; |
|---|
| 944 |
cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); |
|---|
| 945 |
#endif |
|---|
| 946 |
return 1; |
|---|
| 947 |
} |
|---|
| 948 |
|
|---|
| 949 |
|
|---|
| 950 |
|
|---|
| 951 |
void CMakeCommandUsage(const char* program) |
|---|
| 952 |
{ |
|---|
| 953 |
cmOStringStream errorStream; |
|---|
| 954 |
|
|---|
| 955 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 956 |
errorStream |
|---|
| 957 |
<< "cmake version " << cmVersion::GetCMakeVersion() << "\n"; |
|---|
| 958 |
#else |
|---|
| 959 |
errorStream |
|---|
| 960 |
<< "cmake bootstrap\n"; |
|---|
| 961 |
#endif |
|---|
| 962 |
// If you add new commands, change here, |
|---|
| 963 |
// and in cmakemain.cxx in the options table |
|---|
| 964 |
errorStream |
|---|
| 965 |
<< "Usage: " << program << " -E [command] [arguments ...]\n" |
|---|
| 966 |
<< "Available commands: \n" |
|---|
| 967 |
<< " chdir dir cmd [args]... - run command in a given directory\n" |
|---|
| 968 |
<< " rename oldname newname - rename a file or directory " |
|---|
| 969 |
"(on one volume)\n" |
|---|
| 970 |
<< " copy file destination - copy file to destination (either file " |
|---|
| 971 |
"or directory)\n" |
|---|
| 972 |
<< " copy_if_different in-file out-file - copy file if input has " |
|---|
| 973 |
"changed\n" |
|---|
| 974 |
<< " copy_directory source destination - copy directory 'source' " |
|---|
| 975 |
"content to directory 'destination'\n" |
|---|
| 976 |
<< " compare_files file1 file2 - check if file1 is same as file2\n" |
|---|
| 977 |
<< " echo [string]... - displays arguments as text\n" |
|---|
| 978 |
<< " echo_append [string]... - displays arguments as text but no new " |
|---|
| 979 |
"line\n" |
|---|
| 980 |
<< " environment - display the current enviroment\n" |
|---|
| 981 |
<< " make_directory dir - create a directory\n" |
|---|
| 982 |
<< " md5sum file1 [...] - compute md5sum of files\n" |
|---|
| 983 |
<< " remove_directory dir - remove a directory and its contents\n" |
|---|
| 984 |
<< " remove [-f] file1 file2 ... - remove the file(s), use -f to force " |
|---|
| 985 |
"it\n" |
|---|
| 986 |
<< " tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar " |
|---|
| 987 |
"archive\n" |
|---|
| 988 |
<< " time command [args] ... - run command and return elapsed time\n" |
|---|
| 989 |
<< " touch file - touch a file.\n" |
|---|
| 990 |
<< " touch_nocreate file - touch a file but do not create it.\n" |
|---|
| 991 |
<< " build build_dir - build the project in build_dir.\n" |
|---|
| 992 |
#if defined(_WIN32) && !defined(__CYGWIN__) |
|---|
| 993 |
<< " write_regv key value - write registry value\n" |
|---|
| 994 |
<< " delete_regv key - delete registry value\n" |
|---|
| 995 |
<< " comspec - on windows 9x use this for RunCommand\n" |
|---|
| 996 |
#else |
|---|
| 997 |
<< " create_symlink old new - create a symbolic link new -> old\n" |
|---|
| 998 |
#endif |
|---|
| 999 |
; |
|---|
| 1000 |
|
|---|
| 1001 |
cmSystemTools::Error(errorStream.str().c_str()); |
|---|
| 1002 |
} |
|---|
| 1003 |
|
|---|
| 1004 |
int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) |
|---|
| 1005 |
{ |
|---|
| 1006 |
// IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx |
|---|
| 1007 |
if (args.size() > 1) |
|---|
| 1008 |
{ |
|---|
| 1009 |
// Copy file |
|---|
| 1010 |
if (args[1] == "copy" && args.size() == 4) |
|---|
| 1011 |
{ |
|---|
| 1012 |
if(!cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str())) |
|---|
| 1013 |
{ |
|---|
| 1014 |
std::cerr << "Error copying file \"" << args[2].c_str() |
|---|
| 1015 |
<< "\" to \"" << args[3].c_str() << "\".\n"; |
|---|
| 1016 |
return 1; |
|---|
| 1017 |
} |
|---|
| 1018 |
return 0; |
|---|
| 1019 |
} |
|---|
| 1020 |
|
|---|
| 1021 |
// Copy file if different. |
|---|
| 1022 |
if (args[1] == "copy_if_different" && args.size() == 4) |
|---|
| 1023 |
{ |
|---|
| 1024 |
if(!cmSystemTools::CopyFileIfDifferent(args[2].c_str(), |
|---|
| 1025 |
args[3].c_str())) |
|---|
| 1026 |
{ |
|---|
| 1027 |
std::cerr << "Error copying file (if different) from \"" |
|---|
| 1028 |
<< args[2].c_str() << "\" to \"" << args[3].c_str() |
|---|
| 1029 |
<< "\".\n"; |
|---|
| 1030 |
return 1; |
|---|
| 1031 |
} |
|---|
| 1032 |
return 0; |
|---|
| 1033 |
} |
|---|
| 1034 |
|
|---|
| 1035 |
// Copy directory content |
|---|
| 1036 |
if (args[1] == "copy_directory" && args.size() == 4) |
|---|
| 1037 |
{ |
|---|
| 1038 |
if(!cmSystemTools::CopyADirectory(args[2].c_str(), args[3].c_str())) |
|---|
| 1039 |
{ |
|---|
| 1040 |
std::cerr << "Error copying directory from \"" |
|---|
| 1041 |
<< args[2].c_str() << "\" to \"" << args[3].c_str() |
|---|
| 1042 |
<< "\".\n"; |
|---|
| 1043 |
return 1; |
|---|
| 1044 |
} |
|---|
| 1045 |
return 0; |
|---|
| 1046 |
} |
|---|
| 1047 |
|
|---|
| 1048 |
// Rename a file or directory |
|---|
| 1049 |
if (args[1] == "rename" && args.size() == 4) |
|---|
| 1050 |
{ |
|---|
| 1051 |
if(!cmSystemTools::RenameFile(args[2].c_str(), args[3].c_str())) |
|---|
| 1052 |
{ |
|---|
| 1053 |
std::string e = cmSystemTools::GetLastSystemError(); |
|---|
| 1054 |
std::cerr << "Error renaming from \"" |
|---|
| 1055 |
<< args[2].c_str() << "\" to \"" << args[3].c_str() |
|---|
| 1056 |
<< "\": " << e << "\n"; |
|---|
| 1057 |
return 1; |
|---|
| 1058 |
} |
|---|
| 1059 |
return 0; |
|---|
| 1060 |
} |
|---|
| 1061 |
|
|---|
| 1062 |
// Compare files |
|---|
| 1063 |
if (args[1] == "compare_files" && args.size() == 4) |
|---|
| 1064 |
{ |
|---|
| 1065 |
if(cmSystemTools::FilesDiffer(args[2].c_str(), args[3].c_str())) |
|---|
| 1066 |
{ |
|---|
| 1067 |
std::cerr << "Files \"" |
|---|
| 1068 |
<< args[2].c_str() << "\" to \"" << args[3].c_str() |
|---|
| 1069 |
<< "\" are different.\n"; |
|---|
| 1070 |
return 1; |
|---|
| 1071 |
} |
|---|
| 1072 |
return 0; |
|---|
| 1073 |
} |
|---|
| 1074 |
|
|---|
| 1075 |
// Echo string |
|---|
| 1076 |
else if (args[1] == "echo" ) |
|---|
| 1077 |
{ |
|---|
| 1078 |
unsigned int cc; |
|---|
| 1079 |
const char* space = ""; |
|---|
| 1080 |
for ( cc = 2; cc < args.size(); cc ++ ) |
|---|
| 1081 |
{ |
|---|
| 1082 |
std::cout << space << args[cc]; |
|---|
| 1083 |
space = " "; |
|---|
| 1084 |
} |
|---|
| 1085 |
std::cout << std::endl; |
|---|
| 1086 |
return 0; |
|---|
| 1087 |
} |
|---|
| 1088 |
|
|---|
| 1089 |
// Echo string no new line |
|---|
| 1090 |
else if (args[1] == "echo_append" ) |
|---|
| 1091 |
{ |
|---|
| 1092 |
unsigned int cc; |
|---|
| 1093 |
const char* space = ""; |
|---|
| 1094 |
for ( cc = 2; cc < args.size(); cc ++ ) |
|---|
| 1095 |
{ |
|---|
| 1096 |
std::cout << space << args[cc]; |
|---|
| 1097 |
space = " "; |
|---|
| 1098 |
} |
|---|
| 1099 |
return 0; |
|---|
| 1100 |
} |
|---|
| 1101 |
|
|---|
| 1102 |
#if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 1103 |
// Command to create a symbolic link. Fails on platforms not |
|---|
| 1104 |
// supporting them. |
|---|
| 1105 |
else if (args[1] == "environment" ) |
|---|
| 1106 |
{ |
|---|
| 1107 |
std::vector<std::string> env = cmSystemTools::GetEnvironmentVariables(); |
|---|
| 1108 |
std::vector<std::string>::iterator it; |
|---|
| 1109 |
for ( it = env.begin(); it != env.end(); ++ it ) |
|---|
| 1110 |
{ |
|---|
| 1111 |
std::cout << it->c_str() << std::endl; |
|---|
| 1112 |
} |
|---|
| 1113 |
return 0; |
|---|
| 1114 |
} |
|---|
| 1115 |
#endif |
|---|
| 1116 |
|
|---|
| 1117 |
else if (args[1] == "make_directory" && args.size() == 3) |
|---|
| 1118 |
{ |
|---|
| 1119 |
if(!cmSystemTools::MakeDirectory(args[2].c_str())) |
|---|
| 1120 |
{ |
|---|
| 1121 |
std::cerr << "Error making directory \"" << args[2].c_str() |
|---|
| 1122 |
<< "\".\n"; |
|---|
| 1123 |
return 1; |
|---|
| 1124 |
} |
|---|
| 1125 |
return 0; |
|---|
| 1126 |
} |
|---|
| 1127 |
|
|---|
| 1128 |
else if (args[1] == "remove_directory" && args.size() == 3) |
|---|
| 1129 |
{ |
|---|
| 1130 |
if(cmSystemTools::FileIsDirectory(args[2].c_str()) && |
|---|
| 1131 |
!cmSystemTools::RemoveADirectory(args[2].c_str())) |
|---|
| 1132 |
{ |
|---|
| 1133 |
std::cerr << "Error removing directory \"" << args[2].c_str() |
|---|
| 1134 |
<< "\".\n"; |
|---|
| 1135 |
return 1; |
|---|
| 1136 |
} |
|---|
| 1137 |
return 0; |
|---|
| 1138 |
} |
|---|
| 1139 |
|
|---|
| 1140 |
// Remove file |
|---|
| 1141 |
else if (args[1] == "remove" && args.size() > 2) |
|---|
| 1142 |
{ |
|---|
| 1143 |
bool force = false; |
|---|
| 1144 |
for (std::string::size_type cc = 2; cc < args.size(); cc ++) |
|---|
| 1145 |
{ |
|---|
| 1146 |
if(args[cc] == "\\-f" || args[cc] == "-f") |
|---|
| 1147 |
{ |
|---|
| 1148 |
force = true; |
|---|
| 1149 |
} |
|---|
| 1150 |
else |
|---|
| 1151 |
{ |
|---|
| 1152 |
// Complain if the file could not be removed, still exists, |
|---|
| 1153 |
// and the -f option was not given. |
|---|
| 1154 |
if(!cmSystemTools::RemoveFile(args[cc].c_str()) && !force && |
|---|
| 1155 |
cmSystemTools::FileExists(args[cc].c_str())) |
|---|
| 1156 |
{ |
|---|
| 1157 |
return 1; |
|---|
| 1158 |
} |
|---|
| 1159 |
} |
|---|
| 1160 |
} |
|---|
| 1161 |
return 0; |
|---|
| 1162 |
} |
|---|
| 1163 |
// Touch file |
|---|
| 1164 |
else if (args[1] == "touch" && args.size() > 2) |
|---|
| 1165 |
{ |
|---|
| 1166 |
for (std::string::size_type cc = 2; cc < args.size(); cc ++) |
|---|
| 1167 |
{ |
|---|
| 1168 |
// Complain if the file could not be removed, still exists, |
|---|
| 1169 |
// and the -f option was not given. |
|---|
| 1170 |
if(!cmSystemTools::Touch(args[cc].c_str(), true)) |
|---|
| 1171 |
{ |
|---|
| 1172 |
return 1; |
|---|
| 1173 |
} |
|---|
| 1174 |
} |
|---|
| 1175 |
return 0; |
|---|
| 1176 |
} |
|---|
| 1177 |
// Touch file |
|---|
| 1178 |
else if (args[1] == "touch_nocreate" && args.size() > 2) |
|---|
| 1179 |
{ |
|---|
| 1180 |
for (std::string::size_type cc = 2; cc < args.size(); cc ++) |
|---|
| 1181 |
{ |
|---|
| 1182 |
// Complain if the file could not be removed, still exists, |
|---|
| 1183 |
// and the -f option was not given. |
|---|
| 1184 |
if(!cmSystemTools::Touch(args[cc].c_str(), false)) |
|---|
| 1185 |
{ |
|---|
| 1186 |
return 1; |
|---|
| 1187 |
} |
|---|
| 1188 |
} |
|---|
| 1189 |
return 0; |
|---|
| 1190 |
} |
|---|
| 1191 |
|
|---|
| 1192 |
// Clock command |
|---|
| 1193 |
else if (args[1] == "time" && args.size() > 2) |
|---|
| 1194 |
{ |
|---|
| 1195 |
std::string command = args[2]; |
|---|
| 1196 |
for (std::string::size_type cc = 3; cc < args.size(); cc ++) |
|---|
| 1197 |
{ |
|---|
| 1198 |
command += " "; |
|---|
| 1199 |
command += args[cc]; |
|---|
| 1200 |
} |
|---|
| 1201 |
|
|---|
| 1202 |
clock_t clock_start, clock_finish; |
|---|
| 1203 |
time_t time_start, time_finish; |
|---|
| 1204 |
|
|---|
| 1205 |
time(&time_start); |
|---|
| 1206 |
clock_start = clock(); |
|---|
| 1207 |
int ret =0; |
|---|
| 1208 |
cmSystemTools::RunSingleCommand(command.c_str(), 0, &ret); |
|---|
| 1209 |
|
|---|
| 1210 |
clock_finish = clock(); |
|---|
| 1211 |
time(&time_finish); |
|---|
| 1212 |
|
|---|
| 1213 |
double clocks_per_sec = static_cast<double>(CLOCKS_PER_SEC); |
|---|
| 1214 |
std::cout << "Elapsed time: " |
|---|
| 1215 |
<< static_cast<long>(time_finish - time_start) << " s. (time)" |
|---|
| 1216 |
<< ", " |
|---|
| 1217 |
<< static_cast<double>(clock_finish - clock_start) / clocks_per_sec |
|---|
| 1218 |
<< " s. (clock)" |
|---|
| 1219 |
<< "\n"; |
|---|
| 1220 |
return ret; |
|---|
| 1221 |
} |
|---|
| 1222 |
// Command to calculate the md5sum of a file |
|---|
| 1223 |
else if (args[1] == "md5sum" && args.size() >= 3) |
|---|
| 1224 |
{ |
|---|
| 1225 |
char md5out[32]; |
|---|
| 1226 |
int retval = 0; |
|---|
| 1227 |
for (std::string::size_type cc = 2; cc < args.size(); cc ++) |
|---|
| 1228 |
{ |
|---|
| 1229 |
const char *filename = args[cc].c_str(); |
|---|
| 1230 |
// Cannot compute md5sum of a directory |
|---|
| 1231 |
if(cmSystemTools::FileIsDirectory(filename)) |
|---|
| 1232 |
{ |
|---|
| 1233 |
std::cerr << "Error: " << filename << " is a directory" << std::endl; |
|---|
| 1234 |
retval++; |
|---|
| 1235 |
} |
|---|
| 1236 |
else if(!cmSystemTools::ComputeFileMD5(filename, md5out)) |
|---|
| 1237 |
{ |
|---|
| 1238 |
// To mimic md5sum behavior in a shell: |
|---|
| 1239 |
std::cerr << filename << ": No such file or directory" << std::endl; |
|---|
| 1240 |
retval++; |
|---|
| 1241 |
} |
|---|
| 1242 |
else |
|---|
| 1243 |
{ |
|---|
| 1244 |
std::cout << std::string(md5out,32) << " " << filename << std::endl; |
|---|
| 1245 |
} |
|---|
| 1246 |
} |
|---|
| 1247 |
return retval; |
|---|
| 1248 |
} |
|---|
| 1249 |
|
|---|
| 1250 |
// Command to change directory and run a program. |
|---|
| 1251 |
else if (args[1] == "chdir" && args.size() >= 4) |
|---|
| 1252 |
{ |
|---|
| 1253 |
std::string directory = args[2]; |
|---|
| 1254 |
if(!cmSystemTools::FileExists(directory.c_str())) |
|---|
| 1255 |
{ |
|---|
| 1256 |
cmSystemTools::Error("Directory does not exist for chdir command: ", |
|---|
| 1257 |
args[2].c_str()); |
|---|
| 1258 |
return 1; |
|---|
| 1259 |
} |
|---|
| 1260 |
|
|---|
| 1261 |
std::string command = "\""; |
|---|
| 1262 |
command += args[3]; |
|---|
| 1263 |
command += "\""; |
|---|
| 1264 |
for (std::string::size_type cc = 4; cc < args.size(); cc ++) |
|---|
| 1265 |
{ |
|---|
| 1266 |
command += " \""; |
|---|
| 1267 |
command += args[cc]; |
|---|
| 1268 |
command += "\""; |
|---|
| 1269 |
} |
|---|
| 1270 |
int retval = 0; |
|---|
| 1271 |
int timeout = 0; |
|---|
| 1272 |
if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval, |
|---|
| 1273 |
directory.c_str(), true, timeout) ) |
|---|
| 1274 |
{ |
|---|
| 1275 |
return retval; |
|---|
| 1276 |
} |
|---|
| 1277 |
|
|---|
| 1278 |
return 1; |
|---|
| 1279 |
} |
|---|
| 1280 |
|
|---|
| 1281 |
// Command to start progress for a build |
|---|
| 1282 |
else if (args[1] == "cmake_progress_start" && args.size() == 4) |
|---|
| 1283 |
{ |
|---|
| 1284 |
// bascially remove the directory |
|---|
| 1285 |
std::string dirName = args[2]; |
|---|
| 1286 |
dirName += "/Progress"; |
|---|
| 1287 |
cmSystemTools::RemoveADirectory(dirName.c_str()); |
|---|
| 1288 |
|
|---|
| 1289 |
// is the last argument a filename that exists? |
|---|
| 1290 |
FILE *countFile = fopen(args[3].c_str(),"r"); |
|---|
| 1291 |
int count; |
|---|
| 1292 |
if (countFile) |
|---|
| 1293 |
{ |
|---|
| 1294 |
if (1!=fscanf(countFile,"%i",&count)) |
|---|
| 1295 |
{ |
|---|
| 1296 |
cmSystemTools::Message("Could not read from count file."); |
|---|
| 1297 |
} |
|---|
| 1298 |
fclose(countFile); |
|---|
| 1299 |
} |
|---|
| 1300 |
else |
|---|
| 1301 |
{ |
|---|
| 1302 |
count = atoi(args[3].c_str()); |
|---|
| 1303 |
} |
|---|
| 1304 |
if (count) |
|---|
| 1305 |
{ |
|---|
| 1306 |
cmSystemTools::MakeDirectory(dirName.c_str()); |
|---|
| 1307 |
// write the count into the directory |
|---|
| 1308 |
std::string fName = dirName; |
|---|
| 1309 |
fName += "/count.txt"; |
|---|
| 1310 |
FILE *progFile = fopen(fName.c_str(),"w"); |
|---|
| 1311 |
if (progFile) |
|---|
| 1312 |
{ |
|---|
| 1313 |
fprintf(progFile,"%i\n",count); |
|---|
| 1314 |
fclose(progFile); |
|---|
| 1315 |
} |
|---|
| 1316 |
} |
|---|
| 1317 |
return 0; |
|---|
| 1318 |
} |
|---|
| 1319 |
|
|---|
| 1320 |
// Command to report progress for a build |
|---|
| 1321 |
else if (args[1] == "cmake_progress_report" && args.size() >= 3) |
|---|
| 1322 |
{ |
|---|
| 1323 |
std::string dirName = args[2]; |
|---|
| 1324 |
dirName += "/Progress"; |
|---|
| 1325 |
std::string fName; |
|---|
| 1326 |
FILE *progFile; |
|---|
| 1327 |
|
|---|
| 1328 |
// read the count |
|---|
| 1329 |
fName = dirName; |
|---|
| 1330 |
fName += "/count.txt"; |
|---|
| 1331 |
progFile = fopen(fName.c_str(),"r"); |
|---|
| 1332 |
int count = 0; |
|---|
| 1333 |
if (!progFile) |
|---|
| 1334 |
{ |
|---|
| 1335 |
return 0; |
|---|
| 1336 |
} |
|---|
| 1337 |
else |
|---|
| 1338 |
{ |
|---|
| 1339 |
if (1!=fscanf(progFile,"%i",&count)) |
|---|
| 1340 |
{ |
|---|
| 1341 |
cmSystemTools::Message("Could not read from progress file."); |
|---|
| 1342 |
} |
|---|
| 1343 |
fclose(progFile); |
|---|
| 1344 |
} |
|---|
| 1345 |
unsigned int i; |
|---|
| 1346 |
for (i = 3; i < args.size(); ++i) |
|---|
| 1347 |
{ |
|---|
| 1348 |
fName = dirName; |
|---|
| 1349 |
fName += "/"; |
|---|
| 1350 |
fName += args[i]; |
|---|
| 1351 |
progFile = fopen(fName.c_str(),"w"); |
|---|
| 1352 |
if (progFile) |
|---|
| 1353 |
{ |
|---|
| 1354 |
fprintf(progFile,"empty"); |
|---|
| 1355 |
fclose(progFile); |
|---|
| 1356 |
} |
|---|
| 1357 |
} |
|---|
| 1358 |
int fileNum = static_cast<int> |
|---|
| 1359 |
(cmsys::Directory::GetNumberOfFilesInDirectory(dirName.c_str())); |
|---|
| 1360 |
if (count > 0) |
|---|
| 1361 |
{ |
|---|
| 1362 |
// print the progress |
|---|
| 1363 |
fprintf(stdout,"[%3i%%] ",((fileNum-3)*100)/count); |
|---|
| 1364 |
} |
|---|
| 1365 |
return 0; |
|---|
| 1366 |
} |
|---|
| 1367 |
|
|---|
| 1368 |
// Command to create a symbolic link. Fails on platforms not |
|---|
| 1369 |
// supporting them. |
|---|
| 1370 |
else if (args[1] == "create_symlink" && args.size() == 4) |
|---|
| 1371 |
{ |
|---|
| 1372 |
const char* destinationFileName = args[3].c_str(); |
|---|
| 1373 |
if ( cmSystemTools::FileExists(destinationFileName) ) |
|---|
| 1374 |
{ |
|---|
| 1375 |
if ( cmSystemTools::FileIsSymlink(destinationFileName) ) |
|---|
| 1376 |
{ |
|---|
| 1377 |
if ( !cmSystemTools::RemoveFile(destinationFileName) || |
|---|
| 1378 |
cmSystemTools::FileExists(destinationFileName) ) |
|---|
| 1379 |
{ |
|---|
| 1380 |
return 0; |
|---|
| 1381 |
} |
|---|
| 1382 |
} |
|---|
| 1383 |
else |
|---|
| 1384 |
{ |
|---|
| 1385 |
return 0; |
|---|
| 1386 |
} |
|---|
| 1387 |
} |
|---|
| 1388 |
return cmSystemTools::CreateSymlink(args[2].c_str(), |
|---|
| 1389 |
args[3].c_str())? 0:1; |
|---|
| 1390 |
} |
|---|
| 1391 |
|
|---|
| 1392 |
// Internal CMake shared library support. |
|---|
| 1393 |
else if (args[1] == "cmake_symlink_library" && args.size() == 5) |
|---|
| 1394 |
{ |
|---|
| 1395 |
return cmake::SymlinkLibrary(args); |
|---|
| 1396 |
} |
|---|
| 1397 |
// Internal CMake versioned executable support. |
|---|
| 1398 |
else if (args[1] == "cmake_symlink_executable" && args.size() == 4) |
|---|
| 1399 |
{ |
|---|
| 1400 |
return cmake::SymlinkExecutable(args); |
|---|
| 1401 |
} |
|---|
| 1402 |
|
|---|
| 1403 |
#if defined(CMAKE_HAVE_VS_GENERATORS) |
|---|
| 1404 |
// Internal CMake support for calling Visual Studio macros. |
|---|
| 1405 |
else if (args[1] == "cmake_call_visual_studio_macro" && args.size() >= 4) |
|---|
| 1406 |
{ |
|---|
| 1407 |
// args[2] = full path to .sln file or "ALL" |
|---|
| 1408 |
// args[3] = name of Visual Studio macro to call |
|---|
| 1409 |
// args[4..args.size()-1] = [optional] args for Visual Studio macro |
|---|
| 1410 |
|
|---|
| 1411 |
std::string macroArgs; |
|---|
| 1412 |
|
|---|
| 1413 |
if (args.size() > 4) |
|---|
| 1414 |
{ |
|---|
| 1415 |
macroArgs = args[4]; |
|---|
| 1416 |
|
|---|
| 1417 |
for (size_t i = 5; i < args.size(); ++i) |
|---|
| 1418 |
{ |
|---|
| 1419 |
macroArgs += " "; |
|---|
| 1420 |
macroArgs += args[i]; |
|---|
| 1421 |
} |
|---|
| 1422 |
} |
|---|
| 1423 |
|
|---|
| 1424 |
return cmCallVisualStudioMacro::CallMacro(args[2], args[3], |
|---|
| 1425 |
macroArgs, true); |
|---|
| 1426 |
} |
|---|
| 1427 |
#endif |
|---|
| 1428 |
|
|---|
| 1429 |
// Internal CMake dependency scanning support. |
|---|
| 1430 |
else if (args[1] == "cmake_depends" && args.size() >= 6) |
|---|
| 1431 |
{ |
|---|
| 1432 |
// Use the make system's VERBOSE environment variable to enable |
|---|
| 1433 |
// verbose output. This can be skipped by also setting CMAKE_NO_VERBOSE |
|---|
| 1434 |
// (which is set by the Eclipse and KDevelop generators). |
|---|
| 1435 |
bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0) |
|---|
| 1436 |
&& (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0)); |
|---|
| 1437 |
|
|---|
| 1438 |
// Create a cmake object instance to process dependencies. |
|---|
| 1439 |
cmake cm; |
|---|
| 1440 |
std::string gen; |
|---|
| 1441 |
std::string homeDir; |
|---|
| 1442 |
std::string startDir; |
|---|
| 1443 |
std::string homeOutDir; |
|---|
| 1444 |
std::string startOutDir; |
|---|
| 1445 |
std::string depInfo; |
|---|
| 1446 |
bool color = false; |
|---|
| 1447 |
if(args.size() >= 8) |
|---|
| 1448 |
{ |
|---|
| 1449 |
// Full signature: |
|---|
| 1450 |
// |
|---|
| 1451 |
// -E cmake_depends <generator> |
|---|
| 1452 |
// <home-src-dir> <start-src-dir> |
|---|
| 1453 |
// <home-out-dir> <start-out-dir> |
|---|
| 1454 |
// <dep-info> [--color=$(COLOR)] |
|---|
| 1455 |
// |
|---|
| 1456 |
// All paths are provided. |
|---|
| 1457 |
gen = args[2]; |
|---|
| 1458 |
homeDir = args[3]; |
|---|
| 1459 |
startDir = args[4]; |
|---|
| 1460 |
homeOutDir = args[5]; |
|---|
| 1461 |
startOutDir = args[6]; |
|---|
| 1462 |
depInfo = args[7]; |
|---|
| 1463 |
if(args.size() >= 9 && |
|---|
| 1464 |
args[8].length() >= 8 && |
|---|
| 1465 |
args[8].substr(0, 8) == "--color=") |
|---|
| 1466 |
{ |
|---|
| 1467 |
// Enable or disable color based on the switch value. |
|---|
| 1468 |
color = (args[8].size() == 8 || |
|---|
| 1469 |
cmSystemTools::IsOn(args[8].substr(8).c_str())); |
|---|
| 1470 |
} |
|---|
| 1471 |
} |
|---|
| 1472 |
else |
|---|
| 1473 |
{ |
|---|
| 1474 |
// Support older signature for existing makefiles: |
|---|
| 1475 |
// |
|---|
| 1476 |
// -E cmake_depends <generator> |
|---|
| 1477 |
// <home-out-dir> <start-out-dir> |
|---|
| 1478 |
// <dep-info> |
|---|
| 1479 |
// |
|---|
| 1480 |
// Just pretend the source directories are the same as the |
|---|
| 1481 |
// binary directories so at least scanning will work. |
|---|
| 1482 |
gen = args[2]; |
|---|
| 1483 |
homeDir = args[3]; |
|---|
| 1484 |
startDir = args[4]; |
|---|
| 1485 |
homeOutDir = args[3]; |
|---|
| 1486 |
startOutDir = args[3]; |
|---|
| 1487 |
depInfo = args[5]; |
|---|
| 1488 |
} |
|---|
| 1489 |
|
|---|
| 1490 |
// Create a local generator configured for the directory in |
|---|
| 1491 |
// which dependencies will be scanned. |
|---|
| 1492 |
homeDir = cmSystemTools::CollapseFullPath(homeDir.c_str()); |
|---|
| 1493 |
startDir = cmSystemTools::CollapseFullPath(startDir.c_str()); |
|---|
| 1494 |
homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir.c_str()); |
|---|
| 1495 |
startOutDir = cmSystemTools::CollapseFullPath(startOutDir.c_str()); |
|---|
| 1496 |
cm.SetHomeDirectory(homeDir.c_str()); |
|---|
| 1497 |
cm.SetStartDirectory(startDir.c_str()); |
|---|
| 1498 |
cm.SetHomeOutputDirectory(homeOutDir.c_str()); |
|---|
| 1499 |
cm.SetStartOutputDirectory(startOutDir.c_str()); |
|---|
| 1500 |
if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen.c_str())) |
|---|
| 1501 |
{ |
|---|
| 1502 |
cm.SetGlobalGenerator(ggd); |
|---|
| 1503 |
std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); |
|---|
| 1504 |
lgd->GetMakefile()->SetStartDirectory(startDir.c_str()); |
|---|
| 1505 |
lgd->GetMakefile()->SetStartOutputDirectory(startOutDir.c_str()); |
|---|
| 1506 |
lgd->GetMakefile()->MakeStartDirectoriesCurrent(); |
|---|
| 1507 |
|
|---|
| 1508 |
// Actually scan dependencies. |
|---|
| 1509 |
return lgd->UpdateDependencies(depInfo.c_str(), |
|---|
| 1510 |
verbose, color)? 0 : 2; |
|---|
| 1511 |
} |
|---|
| 1512 |
return 1; |
|---|
| 1513 |
} |
|---|
| 1514 |
|
|---|
| 1515 |
// Internal CMake link script support. |
|---|
| 1516 |
else if (args[1] == "cmake_link_script" && args.size() >= 3) |
|---|
| 1517 |
{ |
|---|
| 1518 |
return cmake::ExecuteLinkScript(args); |
|---|
| 1519 |
} |
|---|
| 1520 |
|
|---|
| 1521 |
// Internal CMake unimplemented feature notification. |
|---|
| 1522 |
else if (args[1] == "cmake_unimplemented_variable") |
|---|
| 1523 |
{ |
|---|
| 1524 |
std::cerr << "Feature not implemented for this platform."; |
|---|
| 1525 |
if(args.size() == 3) |
|---|
| 1526 |
{ |
|---|
| 1527 |
std::cerr << " Variable " << args[2] << " is not set."; |
|---|
| 1528 |
} |
|---|
| 1529 |
std::cerr << std::endl; |
|---|
| 1530 |
return 1; |
|---|
| 1531 |
} |
|---|
| 1532 |
else if (args[1] == "vs_link_exe") |
|---|
| 1533 |
{ |
|---|
| 1534 |
return cmake::VisualStudioLink(args, 1); |
|---|
| 1535 |
} |
|---|
| 1536 |
else if (args[1] == "vs_link_dll") |
|---|
| 1537 |
{ |
|---|
| 1538 |
return cmake::VisualStudioLink(args, 2); |
|---|
| 1539 |
} |
|---|
| 1540 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 1541 |
// Internal CMake color makefile support. |
|---|
| 1542 |
else if (args[1] == "cmake_echo_color") |
|---|
| 1543 |
{ |
|---|
| 1544 |
return cmake::ExecuteEchoColor(args); |
|---|
| 1545 |
} |
|---|
| 1546 |
#endif |
|---|
| 1547 |
|
|---|
| 1548 |
// Tar files |
|---|
| 1549 |
else if (args[1] == "tar" && args.size() > 3) |
|---|
| 1550 |
{ |
|---|
| 1551 |
std::string flags = args[2]; |
|---|
| 1552 |
std::string outFile = args[3]; |
|---|
| 1553 |
std::vector<cmStdString> files; |
|---|
| 1554 |
for (std::string::size_type cc = 4; cc < args.size(); cc ++) |
|---|
| 1555 |
{ |
|---|
| 1556 |
files.push_back(args[cc]); |
|---|
| 1557 |
} |
|---|
| 1558 |
bool gzip = false; |
|---|
| 1559 |
bool verbose = false; |
|---|
| 1560 |
if ( flags.find_first_of('z') != flags.npos ) |
|---|
| 1561 |
{ |
|---|
| 1562 |
gzip = true; |
|---|
| 1563 |
} |
|---|
| 1564 |
if ( flags.find_first_of('v') != flags.npos ) |
|---|
| 1565 |
{ |
|---|
| 1566 |
verbose = true; |
|---|
| 1567 |
} |
|---|
| 1568 |
|
|---|
| 1569 |
if ( flags.find_first_of('t') != flags.npos ) |
|---|
| 1570 |
{ |
|---|
| 1571 |
if ( !cmSystemTools::ListTar(outFile.c_str(), files, gzip, verbose) ) |
|---|
| 1572 |
{ |
|---|
| 1573 |
cmSystemTools::Error("Problem creating tar: ", outFile.c_str()); |
|---|
| 1574 |
return 1; |
|---|
| 1575 |
} |
|---|
| 1576 |
} |
|---|
| 1577 |
else if ( flags.find_first_of('c') != flags.npos ) |
|---|
| 1578 |
{ |
|---|
| 1579 |
if ( !cmSystemTools::CreateTar( |
|---|
| 1580 |
outFile.c_str(), files, gzip, verbose) ) |
|---|
| 1581 |
{ |
|---|
| 1582 |
cmSystemTools::Error("Problem creating tar: ", outFile.c_str()); |
|---|
| 1583 |
return 1; |
|---|
| 1584 |
} |
|---|
| 1585 |
} |
|---|
| 1586 |
else if ( flags.find_first_of('x') != flags.npos ) |
|---|
| 1587 |
{ |
|---|
| 1588 |
if ( !cmSystemTools::ExtractTar( |
|---|
| 1589 |
outFile.c_str(), files, gzip, verbose) ) |
|---|
| 1590 |
{ |
|---|
| 1591 |
cmSystemTools::Error("Problem extracting tar: ", outFile.c_str()); |
|---|
| 1592 |
return 1; |
|---|
| 1593 |
} |
|---|
| 1594 |
} |
|---|
| 1595 |
return 0; |
|---|
| 1596 |
} |
|---|
| 1597 |
|
|---|
| 1598 |
#if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 1599 |
// Internal CMake Fortran module support. |
|---|
| 1600 |
else if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) |
|---|
| 1601 |
{ |
|---|
| 1602 |
return cmDependsFortran::CopyModule(args)? 0 : 1; |
|---|
| 1603 |
} |
|---|
| 1604 |
#endif |
|---|
| 1605 |
|
|---|
| 1606 |
#if defined(_WIN32) && !defined(__CYGWIN__) |
|---|
| 1607 |
// Write registry value |
|---|
| 1608 |
else if (args[1] == "write_regv" && args.size() > 3) |
|---|
| 1609 |
{ |
|---|
| 1610 |
return cmSystemTools::WriteRegistryValue(args[2].c_str(), |
|---|
| 1611 |
args[3].c_str()) ? 0 : 1; |
|---|
| 1612 |
} |
|---|
| 1613 |
|
|---|
| 1614 |
// Delete registry value |
|---|
| 1615 |
else if (args[1] == "delete_regv" && args.size() > 2) |
|---|
| 1616 |
{ |
|---|
| 1617 |
return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1; |
|---|
| 1618 |
} |
|---|
| 1619 |
// Remove file |
|---|
| 1620 |
else if (args[1] == "comspec" && args.size() > 2) |
|---|
| 1621 |
{ |
|---|
| 1622 |
unsigned int cc; |
|---|
| 1623 |
std::string command = args[2]; |
|---|
| 1624 |
for ( cc = 3; cc < args.size(); cc ++ ) |
|---|
| 1625 |
{ |
|---|
| 1626 |
command += " " + args[cc]; |
|---|
| 1627 |
} |
|---|
| 1628 |
return cmWin32ProcessExecution::Windows9xHack(command.c_str()); |
|---|
| 1629 |
} |
|---|
| 1630 |
#endif |
|---|
| 1631 |
} |
|---|
| 1632 |
|
|---|
| 1633 |
::CMakeCommandUsage(args[0].c_str()); |
|---|
| 1634 |
return 1; |
|---|
| 1635 |
} |
|---|
| 1636 |
|
|---|
| 1637 |
void cmake::AddExtraGenerator(const char* name, |
|---|
| 1638 |
CreateExtraGeneratorFunctionType newFunction) |
|---|
| 1639 |
{ |
|---|
| 1640 |
cmExternalMakefileProjectGenerator* extraGenerator = newFunction(); |
|---|
| 1641 |
const std::vector<std::string>& supportedGlobalGenerators = |
|---|
| 1642 |
extraGenerator->GetSupportedGlobalGenerators(); |
|---|
| 1643 |
|
|---|
| 1644 |
for(std::vector<std::string>::const_iterator |
|---|
| 1645 |
it = supportedGlobalGenerators.begin(); |
|---|
| 1646 |
it != supportedGlobalGenerators.end(); |
|---|
| 1647 |
++it ) |
|---|
| 1648 |
{ |
|---|
| 1649 |
std::string fullName = cmExternalMakefileProjectGenerator:: |
|---|
| 1650 |
CreateFullGeneratorName(it->c_str(), name); |
|---|
| 1651 |
this->ExtraGenerators[fullName.c_str()] = newFunction; |
|---|
| 1652 |
} |
|---|
| 1653 |
delete extraGenerator; |
|---|
| 1654 |
} |
|---|
| 1655 |
|
|---|
| 1656 |
void cmake::AddDefaultExtraGenerators() |
|---|
| 1657 |
{ |
|---|
| 1658 |
#if defined(CMAKE_BUILD_WITH_CMAKE) |
|---|
| 1659 |
#if defined(_WIN32) && !defined(__CYGWIN__) |
|---|
| 1660 |
// e.g. kdevelop4 ? |
|---|
| 1661 |
#endif |
|---|
| 1662 |
|
|---|
| 1663 |
this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(), |
|---|
| 1664 |
&cmExtraCodeBlocksGenerator::New); |
|---|
| 1665 |
|
|---|
| 1666 |
#ifdef CMAKE_USE_ECLIPSE |
|---|
| 1667 |
this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(), |
|---|
| 1668 |
&cmExtraEclipseCDT4Generator::New); |
|---|
| 1669 |
#endif |
|---|
| 1670 |
|
|---|
| 1671 |
#ifdef CMAKE_USE_KDEVELOP |
|---|
| 1672 |
this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), |
|---|
| 1673 |
&cmGlobalKdevelopGenerator::New); |
|---|
| 1674 |
// for kdevelop also add the generator with just the name of the |
|---|
| 1675 |
// extra generator, since it was this way since cmake 2.2 |
|---|
| 1676 |
this->ExtraGenerators[cmGlobalKdevelopGenerator::GetActualName()] |
|---|
| 1677 |
= &cmGlobalKdevelopGenerator::New; |
|---|
| 1678 |
#endif |
|---|
| 1679 |
|
|---|
| 1680 |
#endif |
|---|
| 1681 |
} |
|---|
| 1682 |
|
|---|
| 1683 |
|
|---|
| 1684 |
//---------------------------------------------------------------------------- |
|---|
| 1685 |
void cmake::GetRegisteredGenerators(std::vector<std::string>& names) |
|---|
| 1686 |
{ |
|---|
| 1687 |
for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin(); |
|---|
| 1688 |
i != this->Generators.end(); ++i) |
|---|
| 1689 |
{ |
|---|
| 1690 |
names.push_back(i->first); |
|---|
| 1691 |
} |
|---|
| 1692 |
for(RegisteredExtraGeneratorsMap::const_iterator |
|---|
| 1693 |
i = this->ExtraGenerators.begin(); |
|---|
| 1694 |
i != this->ExtraGenerators.end(); ++i) |
|---|
| 1695 |
{ |
|---|
| 1696 |
names.push_back(i->first); |
|---|
| 1697 |
} |
|---|
| 1698 |
} |
|---|
| 1699 |
|
|---|
| 1700 |
cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name) |
|---|
| 1701 |
{ |
|---|
| 1702 |
cmGlobalGenerator* generator = 0; |
|---|
| 1703 |
cmExternalMakefileProjectGenerator* extraGenerator = 0; |
|---|
| 1704 |
RegisteredGeneratorsMap::const_iterator genIt = this->Generators.find(name); |
|---|
| 1705 |
if(genIt == this->Generators.end()) |
|---|
| 1706 |
{ |
|---|
| 1707 |
RegisteredExtraGeneratorsMap::const_iterator extraGenIt = |
|---|
| 1708 |
this->ExtraGenerators.find(name); |
|---|
| 1709 |
if (extraGenIt == this->ExtraGenerators.end()) |
|---|
| 1710 |
{ |
|---|
| 1711 |
return 0; |
|---|
| 1712 |
} |
|---|
| 1713 |
extraGenerator = (extraGenIt->second)(); |
|---|
| 1714 |
genIt=this->Generators.find(extraGenerator->GetGlobalGeneratorName(name)); |
|---|
| 1715 |
if(genIt == this->Generators.end()) |
|---|
| 1716 |
{ |
|---|
| 1717 |
delete extraGenerator; |
|---|
| 1718 |
return 0; |
|---|
| 1719 |
} |
|---|
| 1720 |
} |
|---|
| 1721 |
|
|---|
| 1722 |
generator = (genIt->second)(); |
|---|
| 1723 |
generator->SetCMakeInstance(this); |
|---|
| 1724 |
generator->SetExternalMakefileProjectGenerator(extraGenerator); |
|---|
| 1725 |
return generator; |
|---|
| 1726 |
} |
|---|
| 1727 |
|
|---|
| 1728 |
void cmake::SetHomeDirectory(const char* dir) |
|---|
| 1729 |
{ |
|---|
| 1730 |
this->cmHomeDirectory = dir; |
|---|
| 1731 |
cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory); |
|---|
| 1732 |
} |
|---|
| 1733 |
|
|---|
| 1734 |
void cmake::SetHomeOutputDirectory(const char* lib) |
|---|
| 1735 |
{ |
|---|
| 1736 |
this->HomeOutputDirectory = lib; |
|---|
| 1737 |
cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory); |
|---|
| 1738 |
} |
|---|
| 1739 |
|
|---|
| 1740 |
void cmake::SetGlobalGenerator(cmGlobalGenerator *gg) |
|---|
| 1741 |
{ |
|---|
| 1742 |
if(!gg) |
|---|
| 1743 |
{ |
|---|
| 1744 |
cmSystemTools::Error("Error SetGlobalGenerator called with null"); |
|---|
| 1745 |
return; |
|---|
| 1746 |
} |
|---|
| 1747 |
// delete the old generator |
|---|
| 1748 |
if (this->GlobalGenerator) |
|---|
| 1749 |
{ |
|---|
| 1750 |
delete this->GlobalGenerator; |
|---|
| 1751 |
// restore the original environment variables CXX and CC |
|---|
| 1752 |
// Restor CC |
|---|
| 1753 |
std::string env = "CC="; |
|---|
| 1754 |
if(this->CCEnvironment.size()) |
|---|
| 1755 |
{ |
|---|
| 1756 |
env += this->CCEnvironment; |
|---|
| 1757 |
} |
|---|
| 1758 |
cmSystemTools::PutEnv(env.c_str()); |
|---|
| 1759 |
env = "CXX="; |
|---|
| 1760 |
if(this->CXXEnvironment.size()) |
|---|
| 1761 |
{ |
|---|
| 1762 |
env += this->CXXEnvironment; |
|---|
| 1763 |
} |
|---|
| 1764 |
cmSystemTools::PutEnv(env.c_str()); |
|---|
| 1765 |
} |
|---|
| 1766 |
|
|---|
| 1767 |
// set the new |
|---|
| 1768 |
this->GlobalGenerator = gg; |
|---|
| 1769 |
|
|---|
| 1770 |
// set the global flag for unix style paths on cmSystemTools as soon as |
|---|
| 1771 |
// the generator is set. This allows gmake to be used on windows. |
|---|
| 1772 |
cmSystemTools::SetForceUnixPaths |
|---|
| 1773 |
(this->GlobalGenerator->GetForceUnixPaths()); |
|---|
| 1774 |
|
|---|
| 1775 |
// Save the environment variables CXX and CC |
|---|
| 1776 |
const char* cxx = getenv("CXX"); |
|---|
| 1777 |
const char* cc = getenv("CC"); |
|---|
| 1778 |
if(cxx) |
|---|
| 1779 |
{ |
|---|
| 1780 |
this->CXXEnvironment = cxx; |
|---|
| 1781 |
} |
|---|
| 1782 |
else |
|---|
| 1783 |
{ |
|---|
| 1784 |
this->CXXEnvironment = ""; |
|---|
| 1785 |
} |
|---|
| 1786 |
if(cc) |
|---|
| 1787 |
{ |
|---|
| 1788 |
this->CCEnvironment = cc; |
|---|
| 1789 |
} |
|---|
| 1790 |
else |
|---|
| 1791 |
{ |
|---|
| 1792 |
this->CCEnvironment = ""; |
|---|
| 1793 |
} |
|---|
| 1794 |
// set the cmake instance just to be sure |
|---|
| 1795 |
gg->SetCMakeInstance(this); |
|---|
| 1796 |
} |
|---|
| 1797 |
|
|---|
| 1798 |
int cmake::DoPreConfigureChecks() |
|---|
| 1799 |
{ |
|---|
| 1800 |
// Make sure the Start directory contains a CMakeLists.txt file. |
|---|
| 1801 |
std::string srcList = this->GetHomeDirectory(); |
|---|
| 1802 |
srcList += "/CMakeLists.txt"; |
|---|
| 1803 |
if(!cmSystemTools::FileExists(srcList.c_str())) |
|---|
| 1804 |
{ |
|---|
| 1805 |
cmOStringStream err; |
|---|
| 1806 |
if(cmSystemTools::FileIsDirectory(this->GetHomeDirectory())) |
|---|
| 1807 |
{ |
|---|
| 1808 |
err << "The source directory \"" << this->GetHomeDirectory() |
|---|
| 1809 |
<< "\" does not appear to contain CMakeLists.txt.\n"; |
|---|
| 1810 |
} |
|---|
| 1811 |
else if(cmSystemTools::FileExists(this->GetHomeDirectory())) |
|---|
| 1812 |
{ |
|---|
| 1813 |
err << "The source directory \"" << this->GetHomeDirectory() |
|---|
| 1814 |
<< "\" is a file, not a directory.\n"; |
|---|
| 1815 |
} |
|---|
| 1816 |
else |
|---|
| 1817 |
{ |
|---|
| 1818 |
err << "The source directory \"" << this->GetHomeDirectory() |
|---|
| 1819 |
<< "\" does not exist.\n"; |
|---|
| 1820 |
} |
|---|
| 1821 |
err << "Specify --help for usage, or press the help button on the CMake " |
|---|
| 1822 |
"GUI."; |
|---|
| 1823 |
cmSystemTools::Error(err.str().c_str()); |
|---|
| 1824 |
return -2; |
|---|
| 1825 |
} |
|---|
| 1826 |
|
|---|
| 1827 |
// do a sanity check on some values |
|---|
| 1828 |
if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY")) |
|---|
| 1829 |
{ |
|---|
| 1830 |
std::string cacheStart = |
|---|
| 1831 |
this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"); |
|---|
| 1832 |
cacheStart += "/CMakeLists.txt"; |
|---|
| 1833 |
std::string currentStart = this->GetHomeDirectory(); |
|---|
| 1834 |
currentStart += "/CMakeLists.txt"; |
|---|
| 1835 |
if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str())) |
|---|
| 1836 |
{ |
|---|
| 1837 |
std::string message = "The source \""; |
|---|
| 1838 |
message += currentStart; |
|---|
| 1839 |
message += "\" does not match the source \""; |
|---|
| 1840 |
message += cacheStart; |
|---|
| 1841 |
message += "\" used to generate cache. "; |
|---|
| 1842 |
message += "Re-run cmake with a different source directory."; |
|---|
| 1843 |
cmSystemTools::Error(message.c_str()); |
|---|
| 1844 |
return -2; |
|---|
| 1845 |
} |
|---|
| 1846 |
} |
|---|
| 1847 |
else |
|---|
| 1848 |
{ |
|---|
| 1849 |
return 0; |
|---|
| 1850 |
} |
|---|
| 1851 |
return 1; |
|---|
| 1852 |
} |
|---|
| 1853 |
struct SaveCacheEntry |
|---|
| 1854 |
{ |
|---|
| 1855 |
std::string key; |
|---|
| 1856 |
std::string value; |
|---|
| 1857 |
std::string help; |
|---|
| 1858 |
cmCacheManager::CacheEntryType type; |
|---|
| 1859 |
}; |
|---|
| 1860 |
|
|---|
| 1861 |
int cmake::HandleDeleteCacheVariables(const char* var) |
|---|
| 1862 |
{ |
|---|
| 1863 |
std::vector<std::string> argsSplit; |
|---|
| 1864 |
cmSystemTools::ExpandListArgument(std::string(var), argsSplit); |
|---|
| 1865 |
// erase the property to avoid infinite recursion |
|---|
| 1866 |
this->SetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", ""); |
|---|
| 1867 |
if(this->GetIsInTryCompile()) |
|---|
| 1868 |
{ |
|---|
| 1869 |
return 0; |
|---|
| 1870 |
} |
|---|
| 1871 |
cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator(); |
|---|
| 1872 |
std::vector<SaveCacheEntry> saved; |
|---|
| 1873 |
cmOStringStream warning; |
|---|
| 1874 |
warning |
|---|
| 1875 |
<< "You have changed variables that require your cache to be deleted.\n" |
|---|
| 1876 |
<< "Configure will be re-run and you may have to reset some variables.\n" |
|---|
| 1877 |
<< "The following variables have changed:\n"; |
|---|
| 1878 |
for(std::vector<std::string>::iterator i = argsSplit.begin(); |
|---|
| 1879 |
i != argsSplit.end(); ++i) |
|---|
| 1880 |
{ |
|---|
| 1881 |
SaveCacheEntry save; |
|---|
| 1882 |
save.key = *i; |
|---|
| 1883 |
warning << *i << "= "; |
|---|
| 1884 |
i++; |
|---|
| 1885 |
save.value = *i; |
|---|
| 1886 |
warning << *i << "\n"; |
|---|
| 1887 |
if(ci.Find(save.key.c_str())) |
|---|
| 1888 |
{ |
|---|
| 1889 |
save.type = ci.GetType(); |
|---|
| 1890 |
save.help = ci.GetProperty("HELPSTRING"); |
|---|
| 1891 |
} |
|---|
| 1892 |
saved.push_back(save); |
|---|
| 1893 |
} |
|---|
| 1894 |
|
|---|
| 1895 |
// remove the cache |
|---|
| 1896 |
this->CacheManager->DeleteCache(this->GetStartOutputDirectory()); |
|---|
| 1897 |
// load the empty cache |
|---|
| 1898 |
this->LoadCache(); |
|---|
| 1899 |
// restore the changed compilers |
|---|
| 1900 |
for(std::vector<SaveCacheEntry>::iterator i = saved.begin(); |
|---|
| 1901 |
i != saved.end(); ++i) |
|---|
| 1902 |
{ |
|---|
| 1903 |
this->AddCacheEntry(i->key.c_str(), i->value.c_str(), |
|---|
| 1904 |
i->help.c_str(), i->type); |
|---|
| 1905 |
} |
|---|
| 1906 |
cmSystemTools::Message(warning.str().c_str()); |
|---|
| 1907 |
// avoid reconfigure if there were errors |
|---|
| 1908 |
if(!cmSystemTools::GetErrorOccuredFlag()) |
|---|
| 1909 |
{ |
|---|
| 1910 |
// re-run configure |
|---|
| 1911 |
return this->Configure(); |
|---|
| 1912 |
} |
|---|
| 1913 |
return 0; |
|---|
| 1914 |
} |
|---|
| 1915 |
|
|---|
| 1916 |
int cmake::Configure() |
|---|
| 1917 |
{ |
|---|
| 1918 |
if(this->DoSuppressDevWarnings) |
|---|
| 1919 |
{ |
|---|
| 1920 |
if(this->SuppressDevWarnings) |
|---|
| 1921 |
{ |
|---|
| 1922 |
this->CacheManager-> |
|---|
| 1923 |
AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE", |
|---|
| 1924 |
"Suppress Warnings that are meant for" |
|---|
| 1925 |
" the author of the CMakeLists.txt files.", |
|---|
| 1926 |
cmCacheManager::INTERNAL); |
|---|
| 1927 |
} |
|---|
| 1928 |
else |
|---|
| 1929 |
{ |
|---|
| 1930 |
this->CacheManager-> |
|---|
| 1931 |
AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE", |
|---|
| 1932 |
"Suppress Warnings that are meant for" |
|---|
| 1933 |
" the author of the CMakeLists.txt files.", |
|---|
| 1934 |
cmCacheManager::INTERNAL); |
|---|
| 1935 |
} |
|---|
| 1936 |
} |
|---|
| 1937 |
int ret = this->ActualConfigure(); |
|---|
| 1938 |
const char* delCacheVars = |
|---|
| 1939 |
this->GetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_"); |
|---|
| 1940 |
if(delCacheVars && delCacheVars[0] != 0) |
|---|
| 1941 |
{ |
|---|
| 1942 |
return this->HandleDeleteCacheVariables(delCacheVars); |
|---|
| 1943 |
} |
|---|
| 1944 |
return ret; |
|---|
| 1945 |
|
|---|
| 1946 |
} |
|---|
| 1947 |
|
|---|
| 1948 |
int cmake::ActualConfigure() |
|---|
| 1949 |
{ |
|---|
| 1950 |
// Construct right now our path conversion table before it's too late: |
|---|
| 1951 |
this->UpdateConversionPathTable(); |
|---|
| 1952 |
this->CleanupCommandsAndMacros(); |
|---|
| 1953 |
|
|---|
| 1954 |
int res = 0; |
|---|
| 1955 |
if ( !this->ScriptMode ) |
|---|
| 1956 |
{ |
|---|
| 1957 |
res = this->DoPreConfigureChecks(); |
|---|
| 1958 |
} |
|---|
| 1959 |
if ( res < 0 ) |
|---|
| 1960 |
{ |
|---|
| 1961 |
return -2; |
|---|
| 1962 |
} |
|---|
| 1963 |
if ( !res ) |
|---|
| 1964 |
{ |
|---|
| 1965 |
this->CacheManager->AddCacheEntry |
|---|
| 1966 |
("CMAKE_HOME_DIRECTORY", |
|---|
| 1967 |
this->GetHomeDirectory(), |
|---|
| 1968 |
"Start directory with the top level CMakeLists.txt file for this " |
|---|
| 1969 |
"project", |
|---|
| 1970 |
cmCacheManager::INTERNAL); |
|---|
| 1971 |
} |
|---|
| 1972 |
|
|---|
| 1973 |
// no generator specified on the command line |
|---|
| 1974 |
if(!this->GlobalGenerator) |
|---|
| 1975 |
{ |
|---|
| 1976 |
const char* genName = |
|---|
| 1977 |
this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); |
|---|
| 1978 |
const char* extraGenName = |
|---|
| 1979 |
this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR"); |
|---|
| 1980 |
if(genName) |
|---|
| 1981 |
{ |
|---|
| 1982 |
std::string fullName = cmExternalMakefileProjectGenerator:: |
|---|
| 1983 |
CreateFullGeneratorName(genName, extraGenName); |
|---|
| 1984 |
this->GlobalGenerator = this->CreateGlobalGenerator(fullName.c_str()); |
|---|
| 1985 |
} |
|---|
| 1986 |
if(this->GlobalGenerator) |
|---|
| 1987 |
{ |
|---|
| 1988 |
// set the global flag for unix style paths on cmSystemTools as |
|---|
| 1989 |
// soon as the generator is set. This allows gmake to be used |
|---|
| 1990 |
// on windows. |
|---|
| 1991 |
cmSystemTools::SetForceUnixPaths |
|---|
| 1992 |
(this->GlobalGenerator->GetForceUnixPaths()); |
|---|
| 1993 |
} |
|---|
| 1994 |
else |
|---|
| 1995 |
{ |
|---|
| 1996 |
#if defined(__BORLANDC__) && defined(_WIN32) |
|---|
| 1997 |
this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator); |
|---|
| 1998 |
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW) |
|---|
| 1999 |
std::string installedCompiler; |
|---|
| 2000 |
// Try to find the newest VS installed on the computer and |
|---|
| 2001 |
// use that as a default if -G is not specified |
|---|
| 2002 |
std::string vsregBase = |
|---|
| 2003 |
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\"; |
|---|
| 2004 |
struct VSRegistryEntryName |
|---|
| 2005 |
{ |
|---|
| 2006 |
const char* MSVersion; |
|---|
| 2007 |
const char* GeneratorName; |
|---|
| 2008 |
}; |
|---|
| 2009 |
VSRegistryEntryName version[] = { |
|---|
| 2010 |
{"6.0", "Visual Studio 6"}, |
|---|
| 2011 |
{"7.0", "Visual Studio 7"}, |
|---|
| 2012 |
{"7.1", "Visual Studio 7 .NET 2003"}, |
|---|
| 2013 |
{"8.0", "Visual Studio 8 2005"}, |
|---|
| 2014 |
{"9.0", "Visual Studio 9 2008"}, |
|---|
| 2015 |
{"10.0", "Visual Studio 10"}, |
|---|
| 2016 |
{0, 0}}; |
|---|
| 2017 |
for(int i =0; version[i].MSVersion != 0; i++) |
|---|
| 2018 |
{ |
|---|
| 2019 |
std::string reg = vsregBase + version[i].MSVersion; |
|---|
| 2020 |
reg += ";InstallDir]"; |
|---|
| 2021 |
cmSystemTools::ExpandRegistryValues(reg); |
|---|
| 2022 |
if (!(reg == "/registry")) |
|---|
| 2023 |
{ |
|---|
| 2024 |
installedCompiler = version[i].GeneratorName; |
|---|
| 2025 |
} |
|---|
| 2026 |
} |
|---|
| 2027 |
cmGlobalGenerator* gen |
|---|
| 2028 |
= this->CreateGlobalGenerator(installedCompiler.c_str()); |
|---|
| 2029 |
if(!gen) |
|---|
| 2030 |
{ |
|---|
| 2031 |
gen = new cmGlobalNMakeMakefileGenerator; |
|---|
| 2032 |
} |
|---|
| 2033 |
this->SetGlobalGenerator(gen); |
|---|
| 2034 |
std::cout << "-- Building for: " << gen->GetName() << "\n"; |
|---|
| 2035 |
#else |
|---|
| 2036 |
this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3); |
|---|
| 2037 |
#endif |
|---|
| 2038 |
} |
|---|
| 2039 |
if(!this->GlobalGenerator) |
|---|
| 2040 |
{ |
|---|
| 2041 |
cmSystemTools::Error("Could not create generator"); |
|---|
| 2042 |
return -1; |
|---|
| 2043 |
} |
|---|
| 2044 |
} |
|---|
| 2045 |
|
|---|
| 2046 |
const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); |
|---|
| 2047 |
if(genName) |
|---|
| 2048 |
{ |
|---|
| 2049 |
if(strcmp(this->GlobalGenerator->GetName(), genName) != 0) |
|---|
| 2050 |
{ |
|---|
| 2051 |
std::string message = "Error: generator : "; |
|---|
| 2052 |
message += this->GlobalGenerator->GetName(); |
|---|
| 2053 |
message += "\nDoes not match the generator used previously: "; |
|---|
| 2054 |
message += genName; |
|---|
| 2055 |
message += |
|---|
| 2056 |
"\nEither remove the CMakeCache.txt file or choose a different" |
|---|
| 2057 |
" binary directory."; |
|---|
| 2058 |
cmSystemTools::Error(message.c_str()); |
|---|
| 2059 |
return -2; |
|---|
| 2060 |
} |
|---|
| 2061 |
} |
|---|
| 2062 |
if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR")) |
|---|
| 2063 |
{ |
|---|
| 2064 |
this->CacheManager->AddCacheEntry("CMAKE_GENERATOR", |
|---|
| 2065 |
this->GlobalGenerator->GetName(), |
|---|
| 2066 |
"Name of generator.", |
|---|
| 2067 |
cmCacheManager::INTERNAL); |
|---|
| 2068 |
this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR", |
|---|
| 2069 |
this->GlobalGenerator->GetExtraGeneratorName(), |
|---|
| 2070 |
"Name of external makefile project generator.", |
|---|
| 2071 |
cmCacheManager::INTERNAL); |
|---|
| 2072 |
} |
|---|
| 2073 |
|
|---|
| 2074 |
// reset any system configuration information, except for when we are |
|---|
| 2075 |
// InTryCompile. With TryCompile the system info is taken from the parent's |
|---|
| 2076 |
// info to save time |
|---|
| 2077 |
if (!this->InTryCompile) |
|---|
| 2078 |
{ |
|---|
| 2079 |
this->GlobalGenerator->ClearEnabledLanguages(); |
|---|
| 2080 |
} |
|---|
| 2081 |
|
|---|
| 2082 |
// Truncate log files |
|---|
| 2083 |
if (!this->InTryCompile) |
|---|
| 2084 |
{ |
|---|
| 2085 |
this->TruncateOutputLog("CMakeOutput.log"); |
|---|
| 2086 |
this->TruncateOutputLog("CMakeError.log"); |
|---|
| 2087 |
} |
|---|
| 2088 |
|
|---|
| 2089 |
// actually do the configure |
|---|
| 2090 |
this->GlobalGenerator->Configure(); |
|---|
| 2091 |
// Before saving the cache |
|---|
| 2092 |
// if the project did not define one of the entries below, add them now |
|---|
| 2093 |
// so users can edit the values in the cache: |
|---|
| 2094 |
|
|---|
| 2095 |
// We used to always present LIBRARY_OUTPUT_PATH and |
|---|
| 2096 |
// EXECUTABLE_OUTPUT_PATH. They are now documented as old-style and |
|---|
| 2097 |
// should no longer be used. Therefore we present them only if the |
|---|
| 2098 |
// project requires compatibility with CMake 2.4. We detect this |
|---|
| 2099 |
// here by looking for the old CMAKE_BACKWARDS_COMPATABILITY |
|---|
| 2100 |
// variable created when CMP0001 is not set to NEW. |
|---|
| 2101 |
if(this->GetCacheManager()->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")) |
|---|
| 2102 |
{ |
|---|
| 2103 |
if(!this->CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH")) |
|---|
| 2104 |
{ |
|---|
| 2105 |
this->CacheManager->AddCacheEntry |
|---|
| 2106 |
("LIBRARY_OUTPUT_PATH", "", |
|---|
| 2107 |
"Single output directory for building all libraries.", |
|---|
| 2108 |
cmCacheManager::PATH); |
|---|
| 2109 |
} |
|---|
| 2110 |
if(!this->CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH")) |
|---|
| 2111 |
{ |
|---|
| 2112 |
this->CacheManager->AddCacheEntry |
|---|
| 2113 |
("EXECUTABLE_OUTPUT_PATH", "", |
|---|
| 2114 |
"Single output directory for building all executables.", |
|---|
| 2115 |
cmCacheManager::PATH); |
|---|
| 2116 |
} |
|---|
| 2117 |
} |
|---|
| 2118 |
if(!this->CacheManager->GetCacheValue("CMAKE_USE_RELATIVE_PATHS")) |
|---|
| 2119 |
{ |
|---|
| 2120 |
this->CacheManager->AddCacheEntry |
|---|
| 2121 |
("CMAKE_USE_RELATIVE_PATHS", "OFF", |
|---|
| 2122 |
"If true, cmake will use relative paths in makefiles and projects.", |
|---|
| 2123 |
cmCacheManager::BOOL); |
|---|
| 2124 |
cmCacheManager::CacheIterator it = |
|---|
| 2125 |
this->CacheManager->GetCacheIterator("CMAKE_USE_RELATIVE_PATHS"); |
|---|
| 2126 |
if ( !it.PropertyExists("ADVANCED") ) |
|---|
| 2127 |
{ |
|---|
| 2128 |
it.SetProperty("ADVANCED", "1"); |
|---|
| 2129 |
} |
|---|
| 2130 |
} |
|---|
| 2131 |
|
|---|
| 2132 |
if(cmSystemTools::GetFatalErrorOccured() && |
|---|
| 2133 |
(!this->CacheManager->GetCacheValue("CMAKE_MAKE_PROGRAM") || |
|---|
| 2134 |
cmSystemTools::IsOff(this->CacheManager-> |
|---|
| 2135 |
GetCacheValue("CMAKE_MAKE_PROGRAM")))) |
|---|
| 2136 |
{ |
|---|
| 2137 |
// We must have a bad generator selection. Wipe the cache entry so the |
|---|
| 2138 |
// user can select another. |
|---|
| 2139 |
this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR"); |
|---|
| 2140 |
this->CacheManager->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR"); |
|---|
| 2141 |
} |
|---|
| 2142 |
// only save the cache if there were no fatal errors |
|---|
| 2143 |
if ( !this->ScriptMode ) |
|---|
| 2144 |
{ |
|---|
| 2145 |
this->CacheManager->SaveCache(this->GetHomeOutputDirectory()); |
|---|
| 2146 |
} |
|---|
| 2147 |
if ( !this->GraphVizFile.empty() ) |
|---|
| 2148 |
{ |
|---|
| 2149 |
std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl; |
|---|
| 2150 |
this->GenerateGraphViz(this->GraphVizFile.c_str()); |
|---|
| 2151 |
} |
|---|
| 2152 |
if(cmSystemTools::GetErrorOccuredFlag()) |
|---|
| 2153 |
{ |
|---|
| 2154 |
return -1; |
|---|
| 2155 |
} |
|---|
| 2156 |
return 0; |
|---|
| 2157 |
} |
|---|
| 2158 |
|
|---|
| 2159 |
void cmake::PreLoadCMakeFiles() |
|---|
| 2160 |
{ |
|---|
| 2161 |
std::string pre_load = this->GetHomeDirectory(); |
|---|
| 2162 |
if ( pre_load.size() > 0 ) |
|---|
| 2163 |
{ |
|---|
| 2164 |
pre_load += "/PreLoad.cmake"; |
|---|
| 2165 |
if ( cmSystemTools::FileExists(pre_load.c_str()) ) |
|---|
| 2166 |
{ |
|---|
| 2167 |
this->ReadListFile(pre_load.c_str()); |
|---|
| 2168 |
} |
|---|
| 2169 |
} |
|---|
| 2170 |
pre_load = this->GetHomeOutputDirectory(); |
|---|
| 2171 |
if ( pre_load.size() > 0 ) |
|---|
| 2172 |
{ |
|---|
| 2173 |
pre_load += "/PreLoad.cmake"; |
|---|
| 2174 |
if ( cmSystemTools::FileExists(pre_load.c_str()) ) |
|---|
| 2175 |
{ |
|---|
| 2176 |
this->ReadListFile(pre_load.c_str()); |
|---|
| 2177 |
} |
|---|
| 2178 |
} |
|---|
| 2179 |
} |
|---|
| 2180 |
|
|---|
| 2181 |
// handle a command line invocation |
|---|
| 2182 |
int cmake::Run(const std::vector<std::string>& args, bool noconfigure) |
|---|
| 2183 |
{ |
|---|
| 2184 |
// Process the arguments |
|---|
| 2185 |
this->SetArgs(args); |
|---|
| 2186 |
if(cmSystemTools::GetErrorOccuredFlag()) |
|---|
| 2187 |
{ |
|---|
| 2188 |
return -1; |
|---|
| 2189 |
} |
|---|
| 2190 |
|
|---|
| 2191 |
// If we are given a stamp list file check if it is really out of date. |
|---|
| 2192 |
if(!this->CheckStampList.empty() && |
|---|
| 2193 |
cmakeCheckStampList(this->CheckStampList.c_str())) |
|---|
| 2194 |
{ |
|---|
| 2195 |
return 0; |
|---|
| 2196 |
} |
|---|
| 2197 |
|
|---|
| 2198 |
// If we are given a stamp file check if it is really out of date. |
|---|
| 2199 |
if(!this->CheckStampFile.empty() && |
|---|
| 2200 |
cmakeCheckStampFile(this->CheckStampFile.c_str())) |
|---|
| 2201 |
{ |
|---|
| 2202 |
return 0; |
|---|
| 2203 |
} |
|---|
| 2204 |
|
|---|
| 2205 |
// set the cmake command |
|---|
| 2206 |
this->CMakeCommand = args[0]; |
|---|
| 2207 |
|
|---|
| 2208 |
if ( !this->ScriptMode ) |
|---|
| 2209 |
{ |
|---|
| 2210 |
// load the cache |
|---|
| 2211 |
if(this->LoadCache() < 0) |
|---|
| 2212 |
{ |
|---|
| 2213 |
cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n"); |
|---|
| 2214 |
return -1; |
|---|
| 2215 |
} |
|---|
| 2216 |
} |
|---|
| 2217 |
else |
|---|
| 2218 |
{ |
|---|
| 2219 |
this->AddCMakePaths(); |
|---|
| 2220 |
} |
|---|
| 2221 |
// Add any cache args |
|---|
| 2222 |
if ( !this->SetCacheArgs(args) ) |
|---|
| 2223 |
{ |
|---|
| 2224 |
cmSystemTools::Error("Problem processing arguments. Aborting.\n"); |
|---|
| 2225 |
return -1; |
|---|
| 2226 |
} |
|---|
| 2227 |
|
|---|
| 2228 |
// In script mode we terminate after running the script. |
|---|
| 2229 |
if(this->ScriptMode) |
|---|
| 2230 |
{ |
|---|
| 2231 |
if(cmSystemTools::GetErrorOccuredFlag()) |
|---|
| 2232 |
{ |
|---|
| 2233 |
return -1; |
|---|
| 2234 |
} |
|---|
| 2235 |
else |
|---|
| 2236 |
{ |
|---|
| 2237 |
return 0; |
|---|
| 2238 |
} |
|---|
| 2239 |
} |
|---|
| 2240 |
|
|---|
| 2241 |
this->PreLoadCMakeFiles(); |
|---|
| 2242 |
|
|---|
| 2243 |
std::string systemFile = this->GetHomeOutputDirectory(); |
|---|
| 2244 |
systemFile += "/CMakeSystem.cmake"; |
|---|
| 2245 |
|
|---|
| 2246 |
if ( noconfigure ) |
|---|
| 2247 |
{ |
|---|
| 2248 |
return 0; |
|---|
| 2249 |
} |
|---|
| 2250 |
|
|---|
| 2251 |
// now run the global generate |
|---|
| 2252 |
// Check the state of the build system to see if we need to regenerate. |
|---|
| 2253 |
if(!this->CheckBuildSystem()) |
|---|
| 2254 |
{ |
|---|
| 2255 |
return 0; |
|---|
| 2256 |
} |
|---|
| 2257 |
|
|---|
| 2258 |
// If we are doing global generate, we better set start and start |
|---|
| 2259 |
// output directory to the root of the project. |
|---|
| 2260 |
std::string oldstartdir = this->GetStartDirectory(); |
|---|
| 2261 |
std::string oldstartoutputdir = this->GetStartOutputDirectory(); |
|---|
| 2262 |
this->SetStartDirectory(this->GetHomeDirectory()); |
|---|
| 2263 |
this->SetStartOutputDirectory(this->GetHomeOutputDirectory()); |
|---|
| 2264 |
int ret = this->Configure(); |
|---|
| 2265 |
if (ret || this->ScriptMode) |
|---|
| 2266 |
{ |
|---|
| 2267 |
#if defined(CMAKE_HAVE_VS_GENERATORS) |
|---|
| 2268 |
if(!this->VSSolutionFile.empty() && this->GlobalGenerator) |
|---|
| 2269 |
{ |
|---|
| 2270 |
// CMake is running to regenerate a Visual Studio build tree |
|---|
| 2271 |
// during a build from the VS IDE. The build files cannot be |
|---|
| 2272 |
// regenerated, so we should stop the build. |
|---|
| 2273 |
cmSystemTools::Message( |
|---|
| 2274 |
"CMake Configure step failed. " |
|---|
| 2275 |
"Build files cannot be regenerated correctly. " |
|---|
| 2276 |
"Attempting to stop IDE build."); |
|---|
| 2277 |
cmGlobalVisualStudioGenerator* gg = |
|---|
| 2278 |
static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator); |
|---|
| 2279 |
gg->CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop, |
|---|
| 2280 |
this->VSSolutionFile.c_str()); |
|---|
| 2281 |
} |
|---|
| 2282 |
#endif |
|---|
| 2283 |
return ret; |
|---|
| 2284 |
} |
|---|
| 2285 |
ret = this->Generate(); |
|---|
| 2286 |
std::string message = "Build files have been written to: "; |
|---|
| 2287 |
message += this->GetHomeOutputDirectory(); |
|---|
| 2288 |
this->UpdateProgress(message.c_str(), -1); |
|---|
| 2289 |
if(ret) |
|---|
| 2290 |
{ |
|---|
| 2291 |
return ret; |
|---|
| 2292 |
} |
|---|
| 2293 |
this->SetStartDirectory(oldstartdir.c_str()); |
|---|
| 2294 |
this->SetStartOutputDirectory(oldstartoutputdir.c_str()); |
|---|
| 2295 |
|
|---|
| 2296 |
return ret; |
|---|
| 2297 |
} |
|---|
| 2298 |
|
|---|
| 2299 |
int cmake::Generate() |
|---|
| 2300 |
{ |
|---|
| 2301 |
if(!this->GlobalGenerator) |
|---|
| 2302 |
{ |
|---|
| 2303 |
return -1; |
|---|
| 2304 |
} |
|---|
| 2305 |
this->GlobalGenerator->Generate(); |
|---|
| 2306 |
if(cmSystemTools::GetErrorOccuredFlag()) |
|---|
| 2307 |
{ |
|---|
| 2308 |
return -1; |
|---|
| 2309 |
} |
|---|
| 2310 |
if (this->GetProperty("REPORT_UNDEFINED_PROPERTIES")) |
|---|
| 2311 |
{ |
|---|
| 2312 |
this->ReportUndefinedPropertyAccesses |
|---|
| 2313 |
(this->GetProperty("REPORT_UNDEFINED_PROPERTIES")); |
|---|
| 2314 |
} |
|---|
| 2315 |
return 0; |
|---|
| 2316 |
} |
|---|
| 2317 |
|
|---|
| 2318 |
void cmake::AddCacheEntry(const char* key, const char* value, |
|---|
| 2319 |
const char* helpString, |
|---|
| 2320 |
int type) |
|---|
| 2321 |
{ |
|---|
| 2322 |
this->CacheManager->AddCacheEntry(key, value, |
|---|
| 2323 |
helpString, |
|---|
| 2324 |
cmCacheManager::CacheEntryType(type)); |
|---|
| 2325 |
} |
|---|
| 2326 |
|
|---|
| 2327 |
const char* cmake::GetCacheDefinition(const char* name) const |
|---|
| 2328 |
{ |
|---|
| 2329 |
return this->CacheManager->GetCacheValue(name); |
|---|
| 2330 |
} |
|---|
| 2331 |
|
|---|
| 2332 |
void cmake::AddDefaultCommands() |
|---|
| 2333 |
{ |
|---|
| 2334 |
std::list<cmCommand*> commands; |
|---|
| 2335 |
GetBootstrapCommands(commands); |
|---|
| 2336 |
GetPredefinedCommands(commands); |
|---|
| 2337 |
for(std::list<cmCommand*>::iterator i = commands.begin(); |
|---|
| 2338 |
i != commands.end(); ++i) |
|---|
| 2339 |
{ |
|---|
| 2340 |
this->AddCommand(*i); |
|---|
| 2341 |
} |
|---|
| 2342 |
} |
|---|
| 2343 |
|
|---|
| 2344 |
void cmake::AddDefaultGenerators() |
|---|
| 2345 |
{ |
|---|
| 2346 |
#if defined(_WIN32) && !defined(__CYGWIN__) |
|---|
| 2347 |
# if !defined(CMAKE_BOOT_MINGW) |
|---|
| 2348 |
this->Generators[cmGlobalVisualStudio6Generator::GetActualName()] = |
|---|
| 2349 |
&cmGlobalVisualStudio6Generator::New; |
|---|
| 2350 |
this->Generators[cmGlobalVisualStudio7Generator::GetActualName()] = |
|---|
| 2351 |
&cmGlobalVisualStudio7Generator::New; |
|---|
| 2352 |
this->Generators[cmGlobalVisualStudio10Generator::GetActualName()] = |
|---|
| 2353 |
&cmGlobalVisualStudio10Generator::New; |
|---|
| 2354 |
this->Generators[cmGlobalVisualStudio10Win64Generator::GetActualName()] = |
|---|
| 2355 |
&cmGlobalVisualStudio10Win64Generator::New; |
|---|
| 2356 |
this->Generators[cmGlobalVisualStudio71Generator::GetActualName()] = |
|---|
| 2357 |
&cmGlobalVisualStudio71Generator::New; |
|---|
| 2358 |
this->Generators[cmGlobalVisualStudio8Generator::GetActualName()] = |
|---|
| 2359 |
&cmGlobalVisualStudio8Generator::New; |
|---|
| 2360 |
this->Generators[cmGlobalVisualStudio9Generator::GetActualName()] = |
|---|
| 2361 |
&cmGlobalVisualStudio9Generator::New; |
|---|
| 2362 |
this->Generators[cmGlobalVisualStudio9Win64Generator::GetActualName()] = |
|---|
| 2363 |
&cmGlobalVisualStudio9Win64Generator::New; |
|---|
| 2364 |
this->Generators[cmGlobalVisualStudio8Win64Generator::GetActualName()] = |
|---|
| 2365 |
&cmGlobalVisualStudio8Win64Generator::New; |
|---|
| 2366 |
this->Generators[cmGlobalBorlandMakefileGenerator::GetActualName()] = |
|---|
| 2367 |
&cmGlobalBorlandMakefileGenerator::New; |
|---|
| 2368 |
this->Generators[cmGlobalNMakeMakefileGenerator::GetActualName()] = |
|---|
| 2369 |
&cmGlobalNMakeMakefileGenerator::New; |
|---|
| 2370 |
this->Generators[cmGlobalJOMMakefileGenerator::GetActualName()] = |
|---|
| 2371 |
&cmGlobalJOMMakefileGenerator::New; |
|---|
| 2372 |
this->Generators[cmGlobalWatcomWMakeGenerator::GetActualName()] = |
|---|
| 2373 |
&cmGlobalWatcomWMakeGenerator::New; |
|---|
| 2374 |
# endif |
|---|
| 2375 |
this->Generators[cmGlobalMSYSMakefileGenerator::GetActualName()] = |
|---|
| 2376 |
&cmGlobalMSYSMakefileGenerator::New; |
|---|
| 2377 |
this->Generators[cmGlobalMinGWMakefileGenerator::GetActualName()] = |
|---|
| 2378 |
&cmGlobalMinGWMakefileGenerator::New; |
|---|
| 2379 |
#endif |
|---|
| 2380 |
|
|---|
| 2381 |
// //////////////////////////////////////////////////// |
|---|
| 2382 |
// Modified by OSRail Project to create a CodeBlocks |
|---|
| 2383 |
// generator for gcc projects. sehenley@comcast.net |
|---|
| 2384 |
// /////////////////////////////////////////////////// |
|---|
| 2385 |
this->Generators[cmGlobalCodeBlocksGenerator::GetActualName()] = |
|---|
| 2386 |
&cmGlobalCodeBlocksGenerator::New; |
|---|
| 2387 |
// //////////////////////////////////////////////////// |
|---|
| 2388 |
|
|---|
| 2389 |
|
|---|
| 2390 |
this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] = |
|---|
| 2391 |
&cmGlobalUnixMakefileGenerator3::New; |
|---|
| 2392 |
#ifdef CMAKE_USE_XCODE |
|---|
| 2393 |
this->Generators[cmGlobalXCodeGenerator::GetActualName()] = |
|---|
| 2394 |
&cmGlobalXCodeGenerator::New; |
|---|
| 2395 |
#endif |
|---|
| 2396 |
} |
|---|
| 2397 |
|
|---|
| 2398 |
int cmake::LoadCache() |
|---|
| 2399 |
{ |
|---|
| 2400 |
// could we not read the cache |
|---|
| 2401 |
if (!this->CacheManager->LoadCache(this->GetHomeOutputDirectory())) |
|---|
| 2402 |
{ |
|---|
| 2403 |
// if it does exist, but isn;t readable then warn the user |
|---|
| 2404 |
std::string cacheFile = this->GetHomeOutputDirectory(); |
|---|
| 2405 |
cacheFile += "/CMakeCache.txt"; |
|---|
| 2406 |
if(cmSystemTools::FileExists(cacheFile.c_str())) |
|---|
| 2407 |
{ |
|---|
| 2408 |
cmSystemTools::Error( |
|---|
| 2409 |
"There is a CMakeCache.txt file for the current binary tree but " |
|---|
| 2410 |
"cmake does not have permission to read it. Please check the " |
|---|
| 2411 |
"permissions of the directory you are trying to run CMake on."); |
|---|
| 2412 |
return -1; |
|---|
| 2413 |
} |
|---|
| 2414 |
} |
|---|
| 2415 |
|
|---|
| 2416 |
if (this->CMakeCommand.size() < 2) |
|---|
| 2417 |
{ |
|---|
| 2418 |
cmSystemTools::Error( |
|---|
| 2419 |
"cmake command was not specified prior to loading the cache in " |
|---|
| 2420 |
"cmake.cxx"); |
|---|
| 2421 |
return -1; |
|---|
| 2422 |
} |
|---|
| 2423 |
|
|---|
| 2424 |
// setup CMAKE_ROOT and CMAKE_COMMAND |
|---|
| 2425 |
if(!this->AddCMakePaths()) |
|---|
| 2426 |
{ |
|---|
| 2427 |
return -3; |
|---|
| 2428 |
} |
|---|
| 2429 |
return 0; |
|---|
| 2430 |
} |
|---|
| 2431 |
|
|---|
| 2432 |
void cmake::SetProgressCallback(ProgressCallbackType f, void *cd) |
|---|
| 2433 |
{ |
|---|
| 2434 |
this->ProgressCallback = f; |
|---|
| 2435 |
this->ProgressCallbackClientData = cd; |
|---|
| 2436 |
} |
|---|
| 2437 |
|
|---|
| 2438 |
void cmake::UpdateProgress(const char *msg, float prog) |
|---|
| 2439 |
{ |
|---|
| 2440 |
if(this->ProgressCallback && !this->InTryCompile) |
|---|
| 2441 |
{ |
|---|
| 2442 |
(*this->ProgressCallback)(msg, prog, this->ProgressCallbackClientData); |
|---|
| 2443 |
return; |
|---|
| 2444 |
} |
|---|
| 2445 |
} |
|---|
| 2446 |
|
|---|
| 2447 |
void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v, |
|---|
| 2448 |
bool withCurrentCommands, |
|---|
| 2449 |
bool withCompatCommands) const |
|---|
| 2450 |
{ |
|---|
| 2451 |
for(RegisteredCommandsMap::const_iterator j = this->Commands.begin(); |
|---|
| 2452 |
j != this->Commands.end(); ++j) |
|---|
| 2453 |
{ |
|---|
| 2454 |
if ((( withCompatCommands == false) && ( (*j).second->IsDiscouraged())) |
|---|
| 2455 |
|| ((withCurrentCommands == false) && (!(*j).second->IsDiscouraged()))) |
|---|
| 2456 |
{ |
|---|
| 2457 |
continue; |
|---|
| 2458 |
} |
|---|
| 2459 |
|
|---|
| 2460 |
cmDocumentationEntry e((*j).second->GetName(), |
|---|
| 2461 |
(*j).second->GetTerseDocumentation(), |
|---|
| 2462 |
(*j).second->GetFullDocumentation()); |
|---|
| 2463 |
v.push_back(e); |
|---|
| 2464 |
} |
|---|
| 2465 |
} |
|---|
| 2466 |
|
|---|
| 2467 |
void cmake::GetPolicyDocumentation(std::vector<cmDocumentationEntry>& v) |
|---|
| 2468 |
{ |
|---|
| 2469 |
this->Policies->GetDocumentation(v); |
|---|
| 2470 |
} |
|---|
| 2471 |
|
|---|
| 2472 |
void cmake::GetPropertiesDocumentation(std::map<std::string, |
|---|
| 2473 |
cmDocumentationSection *>& v) |
|---|
| 2474 |
{ |
|---|
| 2475 |
// loop over the properties and put them into the doc structure |
|---|
| 2476 |
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::iterator i; |
|---|
| 2477 |
i = this->PropertyDefinitions.begin(); |
|---|
| 2478 |
for (;i != this->PropertyDefinitions.end(); ++i) |
|---|
| 2479 |
{ |
|---|
| 2480 |
i->second.GetPropertiesDocumentation(v); |
|---|
| 2481 |
} |
|---|
| 2482 |
} |
|---|
| 2483 |
|
|---|
| 2484 |
void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v) |
|---|
| 2485 |
{ |
|---|
| 2486 |
for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin(); |
|---|
| 2487 |
i != this->Generators.end(); ++i) |
|---|
| 2488 |
{ |
|---|
| 2489 |
cmDocumentationEntry e; |
|---|
| 2490 |
cmGlobalGenerator* generator = (i->second)(); |
|---|
| 2491 |
generator->GetDocumentation(e); |
|---|
| 2492 |
delete generator; |
|---|
| 2493 |
v.push_back(e); |
|---|
| 2494 |
} |
|---|
| 2495 |
for(RegisteredExtraGeneratorsMap::const_iterator |
|---|
| 2496 |
i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i) |
|---|
| 2497 |
{ |
|---|
| 2498 |
cmDocumentationEntry e; |
|---|
| 2499 |
cmExternalMakefileProjectGenerator* generator = (i->second)(); |
|---|
| 2500 |
generator->GetDocumentation(e, i->first.c_str()); |
|---|
| 2501 |
e.Name = i->first; |
|---|
| 2502 |
delete generator; |
|---|
| 2503 |
v.push_back(e); |
|---|
| 2504 |
} |
|---|
| 2505 |
} |
|---|
| 2506 |
|
|---|
| 2507 |
void cmake::UpdateConversionPathTable() |
|---|
| 2508 |
{ |
|---|
| 2509 |
// Update the path conversion table with any specified file: |
|---|
| 2510 |
const char* tablepath = |
|---|
| 2511 |
this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE"); |
|---|
| 2512 |
|
|---|
| 2513 |
if(tablepath) |
|---|
| 2514 |
{ |
|---|
| 2515 |
std::ifstream table( tablepath ); |
|---|
| 2516 |
if(!table) |
|---|
| 2517 |
{ |
|---|
| 2518 |
cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", tablepath, |
|---|
| 2519 |
". CMake can not open file."); |
|---|
| 2520 |
cmSystemTools::ReportLastSystemError("CMake can not open file."); |
|---|
| 2521 |
} |
|---|
| 2522 |
else |
|---|
| 2523 |
{ |
|---|
| 2524 |
std::string a, b; |
|---|
| 2525 |
while(!table.eof()) |
|---|
| 2526 |
{ |
|---|
| 2527 |
// two entries per line |
|---|
| 2528 |
table >> a; table >> b; |
|---|
| 2529 |
cmSystemTools::AddTranslationPath( a.c_str(), b.c_str()); |
|---|
| 2530 |
} |
|---|
| 2531 |
} |
|---|
| 2532 |
} |
|---|
| 2533 |
} |
|---|
| 2534 |
|
|---|
| 2535 |
//---------------------------------------------------------------------------- |
|---|
| 2536 |
int cmake::CheckBuildSystem() |
|---|
| 2537 |
{ |
|---|
| 2538 |
// We do not need to rerun CMake. Check dependency integrity. Use |
|---|
| 2539 |
// the make system's VERBOSE environment variable to enable verbose |
|---|
| 2540 |
|
|---|
| 2541 |
// output. This can be skipped by setting CMAKE_NO_VERBOSE (which is set |
|---|
| 2542 |
// by the Eclipse and KDevelop generators). |
|---|
| 2543 |
bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0) |
|---|
| 2544 |
&& (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0)); |
|---|
| 2545 |
|
|---|
| 2546 |
// This method will check the integrity of the build system if the |
|---|
| 2547 |
// option was given on the command line. It reads the given file to |
|---|
| 2548 |
// determine whether CMake should rerun. |
|---|
| 2549 |
|
|---|
| 2550 |
// If no file is provided for the check, we have to rerun. |
|---|
| 2551 |
if(this->CheckBuildSystemArgument.size() == 0) |
|---|
| 2552 |
{ |
|---|
| 2553 |
if(verbose) |
|---|
| 2554 |
{ |
|---|
| 2555 |
cmOStringStream msg; |
|---|
| 2556 |
msg << "Re-run cmake no build system arguments\n"; |
|---|
| 2557 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2558 |
} |
|---|
| 2559 |
return 1; |
|---|
| 2560 |
} |
|---|
| 2561 |
|
|---|
| 2562 |
// If the file provided does not exist, we have to rerun. |
|---|
| 2563 |
if(!cmSystemTools::FileExists(this->CheckBuildSystemArgument.c_str())) |
|---|
| 2564 |
{ |
|---|
| 2565 |
if(verbose) |
|---|
| 2566 |
{ |
|---|
| 2567 |
cmOStringStream msg; |
|---|
| 2568 |
msg << "Re-run cmake missing file: " |
|---|
| 2569 |
<< this->CheckBuildSystemArgument.c_str() << "\n"; |
|---|
| 2570 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2571 |
} |
|---|
| 2572 |
return 1; |
|---|
| 2573 |
} |
|---|
| 2574 |
|
|---|
| 2575 |
// Read the rerun check file and use it to decide whether to do the |
|---|
| 2576 |
// global generate. |
|---|
| 2577 |
cmake cm; |
|---|
| 2578 |
cmGlobalGenerator gg; |
|---|
| 2579 |
gg.SetCMakeInstance(&cm); |
|---|
| 2580 |
std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); |
|---|
| 2581 |
cmMakefile* mf = lg->GetMakefile(); |
|---|
| 2582 |
if(!mf->ReadListFile(0, this->CheckBuildSystemArgument.c_str()) || |
|---|
| 2583 |
cmSystemTools::GetErrorOccuredFlag()) |
|---|
| 2584 |
{ |
|---|
| 2585 |
if(verbose) |
|---|
| 2586 |
{ |
|---|
| 2587 |
cmOStringStream msg; |
|---|
| 2588 |
msg << "Re-run cmake error reading : " |
|---|
| 2589 |
<< this->CheckBuildSystemArgument.c_str() << "\n"; |
|---|
| 2590 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2591 |
} |
|---|
| 2592 |
// There was an error reading the file. Just rerun. |
|---|
| 2593 |
return 1; |
|---|
| 2594 |
} |
|---|
| 2595 |
|
|---|
| 2596 |
if(this->ClearBuildSystem) |
|---|
| 2597 |
{ |
|---|
| 2598 |
// Get the generator used for this build system. |
|---|
| 2599 |
const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR"); |
|---|
| 2600 |
if(!genName || genName[0] == '\0') |
|---|
| 2601 |
{ |
|---|
| 2602 |
genName = "Unix Makefiles"; |
|---|
| 2603 |
} |
|---|
| 2604 |
|
|---|
| 2605 |
// Create the generator and use it to clear the dependencies. |
|---|
| 2606 |
std::auto_ptr<cmGlobalGenerator> |
|---|
| 2607 |
ggd(this->CreateGlobalGenerator(genName)); |
|---|
| 2608 |
if(ggd.get()) |
|---|
| 2609 |
{ |
|---|
| 2610 |
std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); |
|---|
| 2611 |
lgd->ClearDependencies(mf, verbose); |
|---|
| 2612 |
} |
|---|
| 2613 |
} |
|---|
| 2614 |
|
|---|
| 2615 |
// If any byproduct of makefile generation is missing we must re-run. |
|---|
| 2616 |
std::vector<std::string> products; |
|---|
| 2617 |
if(const char* productStr = mf->GetDefinition("CMAKE_MAKEFILE_PRODUCTS")) |
|---|
| 2618 |
{ |
|---|
| 2619 |
cmSystemTools::ExpandListArgument(productStr, products); |
|---|
| 2620 |
} |
|---|
| 2621 |
for(std::vector<std::string>::const_iterator pi = products.begin(); |
|---|
| 2622 |
pi != products.end(); ++pi) |
|---|
| 2623 |
{ |
|---|
| 2624 |
if(!(cmSystemTools::FileExists(pi->c_str()) || |
|---|
| 2625 |
cmSystemTools::FileIsSymlink(pi->c_str()))) |
|---|
| 2626 |
{ |
|---|
| 2627 |
if(verbose) |
|---|
| 2628 |
{ |
|---|
| 2629 |
cmOStringStream msg; |
|---|
| 2630 |
msg << "Re-run cmake, missing byproduct: " << *pi << "\n"; |
|---|
| 2631 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2632 |
} |
|---|
| 2633 |
return 1; |
|---|
| 2634 |
} |
|---|
| 2635 |
} |
|---|
| 2636 |
|
|---|
| 2637 |
// Get the set of dependencies and outputs. |
|---|
| 2638 |
std::vector<std::string> depends; |
|---|
| 2639 |
std::vector<std::string> outputs; |
|---|
| 2640 |
const char* dependsStr = mf->GetDefinition("CMAKE_MAKEFILE_DEPENDS"); |
|---|
| 2641 |
const char* outputsStr = mf->GetDefinition("CMAKE_MAKEFILE_OUTPUTS"); |
|---|
| 2642 |
if(dependsStr && outputsStr) |
|---|
| 2643 |
{ |
|---|
| 2644 |
cmSystemTools::ExpandListArgument(dependsStr, depends); |
|---|
| 2645 |
cmSystemTools::ExpandListArgument(outputsStr, outputs); |
|---|
| 2646 |
} |
|---|
| 2647 |
if(depends.empty() || outputs.empty()) |
|---|
| 2648 |
{ |
|---|
| 2649 |
// Not enough information was provided to do the test. Just rerun. |
|---|
| 2650 |
if(verbose) |
|---|
| 2651 |
{ |
|---|
| 2652 |
cmOStringStream msg; |
|---|
| 2653 |
msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS " |
|---|
| 2654 |
"or CMAKE_MAKEFILE_OUTPUTS :\n"; |
|---|
| 2655 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2656 |
} |
|---|
| 2657 |
return 1; |
|---|
| 2658 |
} |
|---|
| 2659 |
|
|---|
| 2660 |
// Find find the newest dependency. |
|---|
| 2661 |
std::vector<std::string>::iterator dep = depends.begin(); |
|---|
| 2662 |
std::string dep_newest = *dep++; |
|---|
| 2663 |
for(;dep != depends.end(); ++dep) |
|---|
| 2664 |
{ |
|---|
| 2665 |
int result = 0; |
|---|
| 2666 |
if(this->FileComparison->FileTimeCompare(dep_newest.c_str(), |
|---|
| 2667 |
dep->c_str(), &result)) |
|---|
| 2668 |
{ |
|---|
| 2669 |
if(result < 0) |
|---|
| 2670 |
{ |
|---|
| 2671 |
dep_newest = *dep; |
|---|
| 2672 |
} |
|---|
| 2673 |
} |
|---|
| 2674 |
else |
|---|
| 2675 |
{ |
|---|
| 2676 |
if(verbose) |
|---|
| 2677 |
{ |
|---|
| 2678 |
cmOStringStream msg; |
|---|
| 2679 |
msg << "Re-run cmake: build system dependency is missing\n"; |
|---|
| 2680 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2681 |
} |
|---|
| 2682 |
return 1; |
|---|
| 2683 |
} |
|---|
| 2684 |
} |
|---|
| 2685 |
|
|---|
| 2686 |
// Find find the oldest output. |
|---|
| 2687 |
std::vector<std::string>::iterator out = outputs.begin(); |
|---|
| 2688 |
std::string out_oldest = *out++; |
|---|
| 2689 |
for(;out != outputs.end(); ++out) |
|---|
| 2690 |
{ |
|---|
| 2691 |
int result = 0; |
|---|
| 2692 |
if(this->FileComparison->FileTimeCompare(out_oldest.c_str(), |
|---|
| 2693 |
out->c_str(), &result)) |
|---|
| 2694 |
{ |
|---|
| 2695 |
if(result > 0) |
|---|
| 2696 |
{ |
|---|
| 2697 |
out_oldest = *out; |
|---|
| 2698 |
} |
|---|
| 2699 |
} |
|---|
| 2700 |
else |
|---|
| 2701 |
{ |
|---|
| 2702 |
if(verbose) |
|---|
| 2703 |
{ |
|---|
| 2704 |
cmOStringStream msg; |
|---|
| 2705 |
msg << "Re-run cmake: build system output is missing\n"; |
|---|
| 2706 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2707 |
} |
|---|
| 2708 |
return 1; |
|---|
| 2709 |
} |
|---|
| 2710 |
} |
|---|
| 2711 |
|
|---|
| 2712 |
// If any output is older than any dependency then rerun. |
|---|
| 2713 |
{ |
|---|
| 2714 |
int result = 0; |
|---|
| 2715 |
if(!this->FileComparison->FileTimeCompare(out_oldest.c_str(), |
|---|
| 2716 |
dep_newest.c_str(), |
|---|
| 2717 |
&result) || |
|---|
| 2718 |
result < 0) |
|---|
| 2719 |
{ |
|---|
| 2720 |
if(verbose) |
|---|
| 2721 |
{ |
|---|
| 2722 |
cmOStringStream msg; |
|---|
| 2723 |
msg << "Re-run cmake file: " << out_oldest.c_str() |
|---|
| 2724 |
<< " older than: " << dep_newest.c_str() << "\n"; |
|---|
| 2725 |
cmSystemTools::Stdout(msg.str().c_str()); |
|---|
| 2726 |
} |
|---|
| 2727 |
return 1; |
|---|
| 2728 |
} |
|---|
| 2729 |
} |
|---|
| 2730 |
|
|---|
| 2731 |
// No need to rerun. |
|---|
| 2732 |
return 0; |
|---|
| 2733 |
} |
|---|
| 2734 |
|
|---|
| 2735 |
//---------------------------------------------------------------------------- |
|---|
| 2736 |
void cmake::TruncateOutputLog(const char* fname) |
|---|
| 2737 |
{ |
|---|
| 2738 |
std::string fullPath = this->GetHomeOutputDirectory(); |
|---|
| 2739 |
fullPath += "/"; |
|---|
| 2740 |
fullPath += fname; |
|---|
| 2741 |
struct stat st; |
|---|
| 2742 |
if ( ::stat(fullPath.c_str(), &st) ) |
|---|
| 2743 |
{ |
|---|
| 2744 |
return; |
|---|
| 2745 |
} |
|---|
| 2746 |
if ( !this->CacheManager->GetCacheValue("CMAKE_CACHEFILE_DIR") ) |
|---|
| 2747 |
{ |
|---|
| 2748 |
cmSystemTools::RemoveFile(fullPath.c_str()); |
|---|
| 2749 |
return; |
|---|
| 2750 |
} |
|---|
| 2751 |
off_t fsize = st.st_size; |
|---|
| 2752 |
const off_t maxFileSize = 50 * 1024; |
|---|
| 2753 |
if ( fsize < maxFileSize ) |
|---|
| 2754 |
{ |
|---|
| 2755 |
//TODO: truncate file |
|---|
| 2756 |
return; |
|---|
| 2757 |
} |
|---|
| 2758 |
} |
|---|
| 2759 |
|
|---|
| 2760 |
inline std::string removeQuotes(const std::string& s) |
|---|
| 2761 |
{ |
|---|
| 2762 |
if(s[0] == '\"' && s[s.size()-1] == '\"') |
|---|
| 2763 |
{ |
|---|
| 2764 |
return s.substr(1, s.size()-2); |
|---|
| 2765 |
} |
|---|
| 2766 |
return s; |
|---|
| 2767 |
} |
|---|
| 2768 |
|
|---|
| 2769 |
std::string cmake::FindCMakeProgram(const char* name) const |
|---|
| 2770 |
{ |
|---|
| 2771 |
std::string path; |
|---|
| 2772 |
if ((name) && (*name)) |
|---|
| 2773 |
{ |
|---|
| 2774 |
const cmMakefile* mf |
|---|
| 2775 |
= this->GetGlobalGenerator()->GetLocalGenerators()[0]->GetMakefile(); |
|---|
| 2776 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 2777 |
path = mf->GetRequiredDefinition("CMAKE_COMMAND"); |
|---|
| 2778 |
path = removeQuotes(path); |
|---|
| 2779 |
path = cmSystemTools::GetFilenamePath(path.c_str()); |
|---|
| 2780 |
path += "/"; |
|---|
| 2781 |
path += name; |
|---|
| 2782 |
path += cmSystemTools::GetExecutableExtension(); |
|---|
| 2783 |
if(!cmSystemTools::FileExists(path.c_str())) |
|---|
| 2784 |
{ |
|---|
| 2785 |
path = mf->GetRequiredDefinition("CMAKE_COMMAND"); |
|---|
| 2786 |
path = cmSystemTools::GetFilenamePath(path.c_str()); |
|---|
| 2787 |
path += "/Debug/"; |
|---|
| 2788 |
path += name; |
|---|
| 2789 |
path += cmSystemTools::GetExecutableExtension(); |
|---|
| 2790 |
} |
|---|
| 2791 |
if(!cmSystemTools::FileExists(path.c_str())) |
|---|
| 2792 |
{ |
|---|
| 2793 |
path = mf->GetRequiredDefinition("CMAKE_COMMAND"); |
|---|
| 2794 |
path = cmSystemTools::GetFilenamePath(path.c_str()); |
|---|
| 2795 |
path += "/Release/"; |
|---|
| 2796 |
path += name; |
|---|
| 2797 |
path += cmSystemTools::GetExecutableExtension(); |
|---|
| 2798 |
} |
|---|
| 2799 |
#else |
|---|
| 2800 |
// Only for bootstrap |
|---|
| 2801 |
path += mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"); |
|---|
| 2802 |
path += "/"; |
|---|
| 2803 |
path += name; |
|---|
| 2804 |
path += cmSystemTools::GetExecutableExtension(); |
|---|
| 2805 |
#endif |
|---|
| 2806 |
} |
|---|
| 2807 |
return path; |
|---|
| 2808 |
} |
|---|
| 2809 |
|
|---|
| 2810 |
const char* cmake::GetCTestCommand() |
|---|
| 2811 |
{ |
|---|
| 2812 |
if ( this->CTestCommand.empty() ) |
|---|
| 2813 |
{ |
|---|
| 2814 |
this->CTestCommand = this->FindCMakeProgram("ctest"); |
|---|
| 2815 |
} |
|---|
| 2816 |
if ( this->CTestCommand.empty() ) |
|---|
| 2817 |
{ |
|---|
| 2818 |
cmSystemTools::Error("Cannot find the CTest executable"); |
|---|
| 2819 |
this->CTestCommand = "CTEST-COMMAND-NOT-FOUND"; |
|---|
| 2820 |
} |
|---|
| 2821 |
return this->CTestCommand.c_str(); |
|---|
| 2822 |
} |
|---|
| 2823 |
|
|---|
| 2824 |
const char* cmake::GetCPackCommand() |
|---|
| 2825 |
{ |
|---|
| 2826 |
if ( this->CPackCommand.empty() ) |
|---|
| 2827 |
{ |
|---|
| 2828 |
this->CPackCommand = this->FindCMakeProgram("cpack"); |
|---|
| 2829 |
} |
|---|
| 2830 |
if ( this->CPackCommand.empty() ) |
|---|
| 2831 |
{ |
|---|
| 2832 |
cmSystemTools::Error("Cannot find the CPack executable"); |
|---|
| 2833 |
this->CPackCommand = "CPACK-COMMAND-NOT-FOUND"; |
|---|
| 2834 |
} |
|---|
| 2835 |
return this->CPackCommand.c_str(); |
|---|
| 2836 |
} |
|---|
| 2837 |
|
|---|
| 2838 |
void cmake::GenerateGraphViz(const char* fileName) const |
|---|
| 2839 |
{ |
|---|
| 2840 |
cmGeneratedFileStream str(fileName); |
|---|
| 2841 |
if ( !str ) |
|---|
| 2842 |
{ |
|---|
| 2843 |
return; |
|---|
| 2844 |
} |
|---|
| 2845 |
cmake cm; |
|---|
| 2846 |
cmGlobalGenerator ggi; |
|---|
| 2847 |
ggi.SetCMakeInstance(&cm); |
|---|
| 2848 |
std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator()); |
|---|
| 2849 |
cmMakefile *mf = lg->GetMakefile(); |
|---|
| 2850 |
|
|---|
| 2851 |
std::string infile = this->GetHomeOutputDirectory(); |
|---|
| 2852 |
infile += "/CMakeGraphVizOptions.cmake"; |
|---|
| 2853 |
if ( !cmSystemTools::FileExists(infile.c_str()) ) |
|---|
| 2854 |
{ |
|---|
| 2855 |
infile = this->GetHomeDirectory(); |
|---|
| 2856 |
infile += "/CMakeGraphVizOptions.cmake"; |
|---|
| 2857 |
if ( !cmSystemTools::FileExists(infile.c_str()) ) |
|---|
| 2858 |
{ |
|---|
| 2859 |
infile = ""; |
|---|
| 2860 |
} |
|---|
| 2861 |
} |
|---|
| 2862 |
|
|---|
| 2863 |
if ( !infile.empty() ) |
|---|
| 2864 |
{ |
|---|
| 2865 |
if ( !mf->ReadListFile(0, infile.c_str()) ) |
|---|
| 2866 |
{ |
|---|
| 2867 |
cmSystemTools::Error("Problem opening GraphViz options file: ", |
|---|
| 2868 |
infile.c_str()); |
|---|
| 2869 |
return; |
|---|
| 2870 |
} |
|---|
| 2871 |
std::cout << "Read GraphViz options file: " << infile.c_str() |
|---|
| 2872 |
<< std::endl; |
|---|
| 2873 |
} |
|---|
| 2874 |
|
|---|
| 2875 |
#define __set_if_not_set(var, value, cmakeDefinition) \ |
|---|
| 2876 |
const char* var = mf->GetDefinition(cmakeDefinition); \ |
|---|
| 2877 |
if ( !var ) \ |
|---|
| 2878 |
{ \ |
|---|
| 2879 |
var = value; \ |
|---|
| 2880 |
} |
|---|
| 2881 |
__set_if_not_set(graphType, "digraph", "GRAPHVIZ_GRAPH_TYPE"); |
|---|
| 2882 |
__set_if_not_set(graphName, "GG", "GRAPHVIZ_GRAPH_NAME"); |
|---|
| 2883 |
__set_if_not_set(graphHeader, "node [\n fontsize = \"12\"\n];", |
|---|
| 2884 |
"GRAPHVIZ_GRAPH_HEADER"); |
|---|
| 2885 |
__set_if_not_set(graphNodePrefix, "node", "GRAPHVIZ_NODE_PREFIX"); |
|---|
| 2886 |
const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS"); |
|---|
| 2887 |
std::set<cmStdString> ignoreTargetsSet; |
|---|
| 2888 |
if ( ignoreTargets ) |
|---|
| 2889 |
{ |
|---|
| 2890 |
std::vector<std::string> ignoreTargetsVector; |
|---|
| 2891 |
cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector); |
|---|
| 2892 |
std::vector<std::string>::iterator itvIt; |
|---|
| 2893 |
for ( itvIt = ignoreTargetsVector.begin(); |
|---|
| 2894 |
itvIt != ignoreTargetsVector.end(); |
|---|
| 2895 |
++ itvIt ) |
|---|
| 2896 |
{ |
|---|
| 2897 |
ignoreTargetsSet.insert(itvIt->c_str()); |
|---|
| 2898 |
} |
|---|
| 2899 |
} |
|---|
| 2900 |
|
|---|
| 2901 |
str << graphType << " " << graphName << " {" << std::endl; |
|---|
| 2902 |
str << graphHeader << std::endl; |
|---|
| 2903 |
|
|---|
| 2904 |
const cmGlobalGenerator* gg = this->GetGlobalGenerator(); |
|---|
| 2905 |
const std::vector<cmLocalGenerator*>& localGenerators = |
|---|
| 2906 |
gg->GetLocalGenerators(); |
|---|
| 2907 |
std::vector<cmLocalGenerator*>::const_iterator lit; |
|---|
| 2908 |
// for target deps |
|---|
| 2909 |
// 1 - cmake target |
|---|
| 2910 |
// 2 - external target |
|---|
| 2911 |
// 0 - no deps |
|---|
| 2912 |
std::map<cmStdString, int> targetDeps; |
|---|
| 2913 |
std::map<cmStdString, const cmTarget*> targetPtrs; |
|---|
| 2914 |
std::map<cmStdString, cmStdString> targetNamesNodes; |
|---|
| 2915 |
int cnt = 0; |
|---|
| 2916 |
// First pass get the list of all cmake targets |
|---|
| 2917 |
for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit ) |
|---|
| 2918 |
{ |
|---|
| 2919 |
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets()); |
|---|
| 2920 |
cmTargets::const_iterator tit; |
|---|
| 2921 |
for ( tit = targets->begin(); tit != targets->end(); ++ tit ) |
|---|
| 2922 |
{ |
|---|
| 2923 |
const char* realTargetName = tit->first.c_str(); |
|---|
| 2924 |
if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() ) |
|---|
| 2925 |
{ |
|---|
| 2926 |
// Skip ignored targets |
|---|
| 2927 |
continue; |
|---|
| 2928 |
} |
|---|
| 2929 |
//std::cout << "Found target: " << tit->first.c_str() << std::endl; |
|---|
| 2930 |
cmOStringStream ostr; |
|---|
| 2931 |
ostr << graphNodePrefix << cnt++; |
|---|
| 2932 |
targetNamesNodes[realTargetName] = ostr.str(); |
|---|
| 2933 |
targetPtrs[realTargetName] = &tit->second; |
|---|
| 2934 |
} |
|---|
| 2935 |
} |
|---|
| 2936 |
// Ok, now find all the stuff we link to that is not in cmake |
|---|
| 2937 |
for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit ) |
|---|
| 2938 |
{ |
|---|
| 2939 |
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets()); |
|---|
| 2940 |
cmTargets::const_iterator tit; |
|---|
| 2941 |
for ( tit = targets->begin(); tit != targets->end(); ++ tit ) |
|---|
| 2942 |
{ |
|---|
| 2943 |
const cmTarget::LinkLibraryVectorType* ll |
|---|
| 2944 |
= &(tit->second.GetOriginalLinkLibraries()); |
|---|
| 2945 |
cmTarget::LinkLibraryVectorType::const_iterator llit; |
|---|
| 2946 |
const char* realTargetName = tit->first.c_str(); |
|---|
| 2947 |
if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() ) |
|---|
| 2948 |
{ |
|---|
| 2949 |
// Skip ignored targets |
|---|
| 2950 |
continue; |
|---|
| 2951 |
} |
|---|
| 2952 |
if ( ll->size() > 0 ) |
|---|
| 2953 |
{ |
|---|
| 2954 |
targetDeps[realTargetName] = 1; |
|---|
| 2955 |
} |
|---|
| 2956 |
for ( llit = ll->begin(); llit != ll->end(); ++ llit ) |
|---|
| 2957 |
{ |
|---|
| 2958 |
const char* libName = llit->first.c_str(); |
|---|
| 2959 |
std::map<cmStdString, cmStdString>::const_iterator tarIt |
|---|
| 2960 |
= targetNamesNodes.find(libName); |
|---|
| 2961 |
if ( ignoreTargetsSet.find(libName) != ignoreTargetsSet.end() ) |
|---|
| 2962 |
{ |
|---|
| 2963 |
// Skip ignored targets |
|---|
| 2964 |
continue; |
|---|
| 2965 |
} |
|---|
| 2966 |
if ( tarIt == targetNamesNodes.end() ) |
|---|
| 2967 |
{ |
|---|
| 2968 |
cmOStringStream ostr; |
|---|
| 2969 |
ostr << graphNodePrefix << cnt++; |
|---|
| 2970 |
targetDeps[libName] = 2; |
|---|
| 2971 |
targetNamesNodes[libName] = ostr.str(); |
|---|
| 2972 |
//str << " \"" << ostr.c_str() << "\" [ label=\"" << libName |
|---|
| 2973 |
//<< "\" shape=\"ellipse\"];" << std::endl; |
|---|
| 2974 |
} |
|---|
| 2975 |
else |
|---|
| 2976 |
{ |
|---|
| 2977 |
std::map<cmStdString, int>::const_iterator depIt |
|---|
| 2978 |
= targetDeps.find(libName); |
|---|
| 2979 |
if ( depIt == targetDeps.end() ) |
|---|
| 2980 |
{ |
|---|
| 2981 |
targetDeps[libName] = 1; |
|---|
| 2982 |
} |
|---|
| 2983 |
} |
|---|
| 2984 |
} |
|---|
| 2985 |
} |
|---|
| 2986 |
} |
|---|
| 2987 |
|
|---|
| 2988 |
// Write out nodes |
|---|
| 2989 |
std::map<cmStdString, int>::const_iterator depIt; |
|---|
| 2990 |
for ( depIt = targetDeps.begin(); depIt != targetDeps.end(); ++ depIt ) |
|---|
| 2991 |
{ |
|---|
| 2992 |
const char* newTargetName = depIt->first.c_str(); |
|---|
| 2993 |
std::map<cmStdString, cmStdString>::const_iterator tarIt |
|---|
| 2994 |
= targetNamesNodes.find(newTargetName); |
|---|
| 2995 |
if ( tarIt == targetNamesNodes.end() ) |
|---|
| 2996 |
{ |
|---|
| 2997 |
// We should not be here. |
|---|
| 2998 |
std::cout << __LINE__ << " Cannot find library: " << newTargetName |
|---|
| 2999 |
<< " even though it was added in the previous pass" << std::endl; |
|---|
| 3000 |
abort(); |
|---|
| 3001 |
} |
|---|
| 3002 |
|
|---|
| 3003 |
str << " \"" << tarIt->second.c_str() << "\" [ label=\"" |
|---|
| 3004 |
<< newTargetName << "\" shape=\""; |
|---|
| 3005 |
if ( depIt->second == 1 ) |
|---|
| 3006 |
{ |
|---|
| 3007 |
std::map<cmStdString, const cmTarget*>::const_iterator tarTypeIt = |
|---|
| 3008 |
targetPtrs.find(newTargetName); |
|---|
| 3009 |
if ( tarTypeIt == targetPtrs.end() ) |
|---|
| 3010 |
{ |
|---|
| 3011 |
// We should not be here. |
|---|
| 3012 |
std::cout << __LINE__ << " Cannot find library: " << newTargetName |
|---|
| 3013 |
<< " even though it was added in the previous pass" << std::endl; |
|---|
| 3014 |
abort(); |
|---|
| 3015 |
} |
|---|
| 3016 |
const cmTarget* tg = tarTypeIt->second; |
|---|
| 3017 |
switch ( tg->GetType() ) |
|---|
| 3018 |
{ |
|---|
| 3019 |
case cmTarget::EXECUTABLE: |
|---|
| 3020 |
str << "house"; |
|---|
| 3021 |
break; |
|---|
| 3022 |
case cmTarget::STATIC_LIBRARY: |
|---|
| 3023 |
str << "diamond"; |
|---|
| 3024 |
break; |
|---|
| 3025 |
case cmTarget::SHARED_LIBRARY: |
|---|
| 3026 |
str << "polygon"; |
|---|
| 3027 |
break; |
|---|
| 3028 |
case cmTarget::MODULE_LIBRARY: |
|---|
| 3029 |
str << "octagon"; |
|---|
| 3030 |
break; |
|---|
| 3031 |
default: |
|---|
| 3032 |
str << "box"; |
|---|
| 3033 |
} |
|---|
| 3034 |
} |
|---|
| 3035 |
else |
|---|
| 3036 |
{ |
|---|
| 3037 |
str << "ellipse"; |
|---|
| 3038 |
} |
|---|
| 3039 |
str << "\"];" << std::endl; |
|---|
| 3040 |
} |
|---|
| 3041 |
|
|---|
| 3042 |
// Now generate the connectivity |
|---|
| 3043 |
for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit ) |
|---|
| 3044 |
{ |
|---|
| 3045 |
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets()); |
|---|
| 3046 |
cmTargets::const_iterator tit; |
|---|
| 3047 |
for ( tit = targets->begin(); tit != targets->end(); ++ tit ) |
|---|
| 3048 |
{ |
|---|
| 3049 |
std::map<cmStdString, int>::iterator dependIt |
|---|
| 3050 |
= targetDeps.find(tit->first.c_str()); |
|---|
| 3051 |
if ( dependIt == targetDeps.end() ) |
|---|
| 3052 |
{ |
|---|
| 3053 |
continue; |
|---|
| 3054 |
} |
|---|
| 3055 |
std::map<cmStdString, cmStdString>::iterator cmakeTarIt |
|---|
| 3056 |
= targetNamesNodes.find(tit->first.c_str()); |
|---|
| 3057 |
const cmTarget::LinkLibraryVectorType* ll |
|---|
| 3058 |
= &(tit->second.GetOriginalLinkLibraries()); |
|---|
| 3059 |
cmTarget::LinkLibraryVectorType::const_iterator llit; |
|---|
| 3060 |
for ( llit = ll->begin(); llit != ll->end(); ++ llit ) |
|---|
| 3061 |
{ |
|---|
| 3062 |
const char* libName = llit->first.c_str(); |
|---|
| 3063 |
std::map<cmStdString, cmStdString>::const_iterator tarIt |
|---|
| 3064 |
= targetNamesNodes.find(libName); |
|---|
| 3065 |
if ( tarIt == targetNamesNodes.end() ) |
|---|
| 3066 |
{ |
|---|
| 3067 |
// We should not be here. |
|---|
| 3068 |
std::cout << __LINE__ << " Cannot find library: " << libName |
|---|
| 3069 |
<< " even though it was added in the previous pass" << std::endl; |
|---|
| 3070 |
abort(); |
|---|
| 3071 |
} |
|---|
| 3072 |
str << " \"" << cmakeTarIt->second.c_str() << "\" -> \"" |
|---|
| 3073 |
<< tarIt->second.c_str() << "\"" << std::endl; |
|---|
| 3074 |
} |
|---|
| 3075 |
} |
|---|
| 3076 |
} |
|---|
| 3077 |
|
|---|
| 3078 |
// TODO: Use dotted or something for external libraries |
|---|
| 3079 |
//str << " \"node0\":f4 -> \"node12\"[color=\"#0000ff\" style=dotted]" |
|---|
| 3080 |
//<< std::endl; |
|---|
| 3081 |
// |
|---|
| 3082 |
str << "}" << std::endl; |
|---|
| 3083 |
} |
|---|
| 3084 |
|
|---|
| 3085 |
//---------------------------------------------------------------------------- |
|---|
| 3086 |
int cmake::SymlinkLibrary(std::vector<std::string>& args) |
|---|
| 3087 |
{ |
|---|
| 3088 |
int result = 0; |
|---|
| 3089 |
std::string realName = args[2]; |
|---|
| 3090 |
std::string soName = args[3]; |
|---|
| 3091 |
std::string name = args[4]; |
|---|
| 3092 |
if(soName != realName) |
|---|
| 3093 |
{ |
|---|
| 3094 |
if(!cmake::SymlinkInternal(realName, soName)) |
|---|
| 3095 |
{ |
|---|
| 3096 |
cmSystemTools::ReportLastSystemError("cmake_symlink_library"); |
|---|
| 3097 |
result = 1; |
|---|
| 3098 |
} |
|---|
| 3099 |
} |
|---|
| 3100 |
if(name != soName) |
|---|
| 3101 |
{ |
|---|
| 3102 |
if(!cmake::SymlinkInternal(soName, name)) |
|---|
| 3103 |
{ |
|---|
| 3104 |
cmSystemTools::ReportLastSystemError("cmake_symlink_library"); |
|---|
| 3105 |
result = 1; |
|---|
| 3106 |
} |
|---|
| 3107 |
} |
|---|
| 3108 |
return result; |
|---|
| 3109 |
} |
|---|
| 3110 |
|
|---|
| 3111 |
//---------------------------------------------------------------------------- |
|---|
| 3112 |
int cmake::SymlinkExecutable(std::vector<std::string>& args) |
|---|
| 3113 |
{ |
|---|
| 3114 |
int result = 0; |
|---|
| 3115 |
std::string realName = args[2]; |
|---|
| 3116 |
std::string name = args[3]; |
|---|
| 3117 |
if(name != realName) |
|---|
| 3118 |
{ |
|---|
| 3119 |
if(!cmake::SymlinkInternal(realName, name)) |
|---|
| 3120 |
{ |
|---|
| 3121 |
cmSystemTools::ReportLastSystemError("cmake_symlink_executable"); |
|---|
| 3122 |
result = 1; |
|---|
| 3123 |
} |
|---|
| 3124 |
} |
|---|
| 3125 |
return result; |
|---|
| 3126 |
} |
|---|
| 3127 |
|
|---|
| 3128 |
//---------------------------------------------------------------------------- |
|---|
| 3129 |
bool cmake::SymlinkInternal(std::string const& file, std::string const& link) |
|---|
| 3130 |
{ |
|---|
| 3131 |
if(cmSystemTools::FileExists(link.c_str()) || |
|---|
| 3132 |
cmSystemTools::FileIsSymlink(link.c_str())) |
|---|
| 3133 |
{ |
|---|
| 3134 |
cmSystemTools::RemoveFile(link.c_str()); |
|---|
| 3135 |
} |
|---|
| 3136 |
#if defined(_WIN32) && !defined(__CYGWIN__) |
|---|
| 3137 |
return cmSystemTools::CopyFileAlways(file.c_str(), link.c_str()); |
|---|
| 3138 |
#else |
|---|
| 3139 |
std::string linktext = cmSystemTools::GetFilenameName(file); |
|---|
| 3140 |
return cmSystemTools::CreateSymlink(linktext.c_str(), link.c_str()); |
|---|
| 3141 |
#endif |
|---|
| 3142 |
} |
|---|
| 3143 |
|
|---|
| 3144 |
//---------------------------------------------------------------------------- |
|---|
| 3145 |
#ifdef CMAKE_BUILD_WITH_CMAKE |
|---|
| 3146 |
int cmake::ExecuteEchoColor(std::vector<std::string>& args) |
|---|
| 3147 |
{ |
|---|
| 3148 |
// The arguments are |
|---|
| 3149 |
// argv[0] == <cmake-executable> |
|---|
| 3150 |
// argv[1] == cmake_echo_color |
|---|
| 3151 |
|
|---|
| 3152 |
bool enabled = true; |
|---|
| 3153 |
int color = cmsysTerminal_Color_Normal; |
|---|
| 3154 |
bool newline = true; |
|---|
| 3155 |
for(unsigned int i=2; i < args.size(); ++i) |
|---|
| 3156 |
{ |
|---|
| 3157 |
if(args[i].find("--switch=") == 0) |
|---|
| 3158 |
{ |
|---|
| 3159 |
// Enable or disable color based on the switch value. |
|---|
| 3160 |
std::string value = args[i].substr(9); |
|---|
| 3161 |
if(!value.empty()) |
|---|
| 3162 |
{ |
|---|
| 3163 |
if(cmSystemTools::IsOn(value.c_str())) |
|---|
| 3164 |
{ |
|---|
| 3165 |
enabled = true; |
|---|
| 3166 |
} |
|---|
| 3167 |
else |
|---|
| 3168 |
{ |
|---|
| 3169 |
enabled = false; |
|---|
| 3170 |
} |
|---|
| 3171 |
} |
|---|
| 3172 |
} |
|---|
| 3173 |
else if(args[i] == "--normal") |
|---|
| 3174 |
{ |
|---|
| 3175 |
color = cmsysTerminal_Color_Normal; |
|---|
| 3176 |
} |
|---|
| 3177 |
else if(args[i] == "--black") |
|---|
| 3178 |
{ |
|---|
| 3179 |
color = cmsysTerminal_Color_ForegroundBlack; |
|---|
| 3180 |
} |
|---|
| 3181 |
else if(args[i] == "--red") |
|---|
| 3182 |
{ |
|---|
| 3183 |
color = cmsysTerminal_Color_ForegroundRed; |
|---|
| 3184 |
} |
|---|
| 3185 |
else if(args[i] == "--green") |
|---|
| 3186 |
{ |
|---|
| 3187 |
color = cmsysTerminal_Color_ForegroundGreen; |
|---|
| 3188 |
} |
|---|
| 3189 |
else if(args[i] == "--yellow") |
|---|
| 3190 |
{ |
|---|
| 3191 |
color = cmsysTerminal_Color_ForegroundYellow; |
|---|
| 3192 |
} |
|---|
| 3193 |
else if(args[i] == "--blue") |
|---|
| 3194 |
{ |
|---|
| 3195 |
color = cmsysTerminal_Color_ForegroundBlue; |
|---|
| 3196 |
} |
|---|
| 3197 |
else if(args[i] == "--magenta") |
|---|
| 3198 |
{ |
|---|
| 3199 |
color = cmsysTerminal_Color_ForegroundMagenta; |
|---|
| 3200 |
} |
|---|
| 3201 |
else if(args[i] == "--cyan") |
|---|
| 3202 |
{ |
|---|
| 3203 |
color = cmsysTerminal_Color_ForegroundCyan; |
|---|
| 3204 |
} |
|---|
| 3205 |
else if(args[i] == "--white") |
|---|
| 3206 |
{ |
|---|
| 3207 |
color = cmsysTerminal_Color_ForegroundWhite; |
|---|
| 3208 |
} |
|---|
| 3209 |
else if(args[i] == "--bold") |
|---|
| 3210 |
{ |
|---|
| 3211 |
color |= cmsysTerminal_Color_ForegroundBold; |
|---|
| 3212 |
} |
|---|
| 3213 |
else if(args[i] == "--no-newline") |
|---|
| 3214 |
{ |
|---|
| 3215 |
newline = false; |
|---|
| 3216 |
} |
|---|
| 3217 |
else if(args[i] == "--newline") |
|---|
| 3218 |
{ |
|---|
| 3219 |
newline = true; |
|---|
| 3220 |
} |
|---|
| 3221 |
else |
|---|
| 3222 |
{ |
|---|
| 3223 |
// Color is enabled. Print with the current color. |
|---|
| 3224 |
cmSystemTools::MakefileColorEcho(color, args[i].c_str(), |
|---|
| 3225 |
newline, enabled); |
|---|
| 3226 |
} |
|---|
| 3227 |
} |
|---|
| 3228 |
|
|---|
| 3229 |
return 0; |
|---|
| 3230 |
} |
|---|
| 3231 |
#else |
|---|
| 3232 |
int cmake::ExecuteEchoColor(std::vector<std::string>&) |
|---|
| 3233 |
{ |
|---|
| 3234 |
return 1; |
|---|
| 3235 |
} |
|---|
| 3236 |
#endif |
|---|
| 3237 |
|
|---|
| 3238 |
//---------------------------------------------------------------------------- |
|---|
| 3239 |
int cmake::ExecuteLinkScript(std::vector<std::string>& args) |
|---|
| 3240 |
{ |
|---|
| 3241 |
// The arguments are |
|---|
| 3242 |
// argv[0] == <cmake-executable> |
|---|
| 3243 |
// argv[1] == cmake_link_script |
|---|
| 3244 |
// argv[2] == <link-script-name> |
|---|
| 3245 |
// argv[3] == --verbose=? |
|---|
| 3246 |
bool verbose = false; |
|---|
| 3247 |
if(args.size() >= 4) |
|---|
| 3248 |
{ |
|---|
| 3249 |
if(args[3].find("--verbose=") == 0) |
|---|
| 3250 |
{ |
|---|
| 3251 |
if(!cmSystemTools::IsOff(args[3].substr(10).c_str())) |
|---|
| 3252 |
{ |
|---|
| 3253 |
verbose = true; |
|---|
| 3254 |
} |
|---|
| 3255 |
} |
|---|
| 3256 |
} |
|---|
| 3257 |
|
|---|
| 3258 |
// Allocate a process instance. |
|---|
| 3259 |
cmsysProcess* cp = cmsysProcess_New(); |
|---|
| 3260 |
if(!cp) |
|---|
| 3261 |
{ |
|---|
| 3262 |
std::cerr << "Error allocating process instance in link script." |
|---|
| 3263 |
<< std::endl; |
|---|
| 3264 |
return 1; |
|---|
| 3265 |
} |
|---|
| 3266 |
|
|---|
| 3267 |
// Children should share stdout and stderr with this process. |
|---|
| 3268 |
cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1); |
|---|
| 3269 |
cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1); |
|---|
| 3270 |
|
|---|
| 3271 |
// Run the command lines verbatim. |
|---|
| 3272 |
cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1); |
|---|
| 3273 |
|
|---|
| 3274 |
// Read command lines from the script. |
|---|
| 3275 |
std::ifstream fin(args[2].c_str()); |
|---|
| 3276 |
if(!fin) |
|---|
| 3277 |
{ |
|---|
| 3278 |
std::cerr << "Error opening link script \"" |
|---|
| 3279 |
<< args[2] << "\"" << std::endl; |
|---|
| 3280 |
return 1; |
|---|
| 3281 |
} |
|---|
| 3282 |
|
|---|
| 3283 |
// Run one command at a time. |
|---|
| 3284 |
std::string command; |
|---|
| 3285 |
int result = 0; |
|---|
| 3286 |
while(result == 0 && cmSystemTools::GetLineFromStream(fin, command)) |
|---|
| 3287 |
{ |
|---|
| 3288 |
// Setup this command line. |
|---|
| 3289 |
const char* cmd[2] = {command.c_str(), 0}; |
|---|
| 3290 |
cmsysProcess_SetCommand(cp, cmd); |
|---|
| 3291 |
|
|---|
| 3292 |
// Report the command if verbose output is enabled. |
|---|
| 3293 |
if(verbose) |
|---|
| 3294 |
{ |
|---|
| 3295 |
std::cout << command << std::endl; |
|---|
| 3296 |
} |
|---|
| 3297 |
|
|---|
| 3298 |
// Run the command and wait for it to exit. |
|---|
| 3299 |
cmsysProcess_Execute(cp); |
|---|
| 3300 |
cmsysProcess_WaitForExit(cp, 0); |
|---|
| 3301 |
|
|---|
| 3302 |
// Report failure if any. |
|---|
| 3303 |
switch(cmsysProcess_GetState(cp)) |
|---|
| 3304 |
{ |
|---|
| 3305 |
case cmsysProcess_State_Exited: |
|---|
| 3306 |
{ |
|---|
| 3307 |
int value = cmsysProcess_GetExitValue(cp); |
|---|
| 3308 |
if(value != 0) |
|---|
| 3309 |
{ |
|---|
| 3310 |
result = value; |
|---|
| 3311 |
} |
|---|
| 3312 |
} |
|---|
| 3313 |
break; |
|---|
| 3314 |
case cmsysProcess_State_Exception: |
|---|
| 3315 |
std::cerr << "Error running link command: " |
|---|
| 3316 |
<< cmsysProcess_GetExceptionString(cp) << std::endl; |
|---|
| 3317 |
result = 1; |
|---|
| 3318 |
break; |
|---|
| 3319 |
case cmsysProcess_State_Error: |
|---|
| 3320 |
std::cerr << "Error running link command: " |
|---|
| 3321 |
<< cmsysProcess_GetErrorString(cp) << std::endl; |
|---|
| 3322 |
result = 2; |
|---|
| 3323 |
break; |
|---|
| 3324 |
default: |
|---|
| 3325 |
break; |
|---|
| 3326 |
}; |
|---|
| 3327 |
} |
|---|
| 3328 |
|
|---|
| 3329 |
// Free the process instance. |
|---|
| 3330 |
cmsysProcess_Delete(cp); |
|---|
| 3331 |
|
|---|
| 3332 |
// Return the final resulting return value. |
|---|
| 3333 |
return result; |
|---|
| 3334 |
} |
|---|
| 3335 |
|
|---|
| 3336 |
void cmake::DefineProperties(cmake *cm) |
|---|
| 3337 |
{ |
|---|
| 3338 |
cm->DefineProperty |
|---|
| 3339 |
("REPORT_UNDEFINED_PROPERTIES", cmProperty::GLOBAL, |
|---|
| 3340 |
"If set, report any undefined properties to this file.", |
|---|
| 3341 |
"If this property is set to a filename then when CMake runs " |
|---|
| 3342 |
"it will report any properties or variables that were accessed " |
|---|
| 3343 |
"but not defined into the filename specified in this property." |
|---|
| 3344 |
); |
|---|
| 3345 |
|
|---|
| 3346 |
cm->DefineProperty |
|---|
| 3347 |
("TARGET_SUPPORTS_SHARED_LIBS", cmProperty::GLOBAL, |
|---|
| 3348 |
"Does the target platform support shared libraries.", |
|---|
| 3349 |
"TARGET_SUPPORTS_SHARED_LIBS is a boolean specifying whether the target " |
|---|
| 3350 |
"platform supports shared libraries. Basically all current general " |
|---|
| 3351 |
"general purpose OS do so, the exception are usually embedded systems " |
|---|
| 3352 |
"with no or special OSs."); |
|---|
| 3353 |
|
|---|
| 3354 |
cm->DefineProperty |
|---|
| 3355 |
("TARGET_ARCHIVES_MAY_BE_SHARED_LIBS", cmProperty::GLOBAL, |
|---|
| 3356 |
"Set if shared libraries may be named like archives.", |
|---|
| 3357 |
"On AIX shared libraries may be named \"lib<name>.a\". " |
|---|
| 3358 |
"This property is set to true on such platforms."); |
|---|
| 3359 |
|
|---|
| 3360 |
cm->DefineProperty |
|---|
| 3361 |
("FIND_LIBRARY_USE_LIB64_PATHS", cmProperty::GLOBAL, |
|---|
| 3362 |
"Whether FIND_LIBRARY should automatically search lib64 directories.", |
|---|
| 3363 |
"FIND_LIBRARY_USE_LIB64_PATHS is a boolean specifying whether the " |
|---|
| 3364 |
"FIND_LIBRARY command should automatically search the lib64 variant of " |
|---|
| 3365 |
"directories called lib in the search path when building 64-bit " |
|---|
| 3366 |
"binaries."); |
|---|
| 3367 |
cm->DefineProperty |
|---|
| 3368 |
("FIND_LIBRARY_USE_OPENBSD_VERSIONING", cmProperty::GLOBAL, |
|---|
| 3369 |
"Whether FIND_LIBRARY should find OpenBSD-style shared libraries.", |
|---|
| 3370 |
"This property is a boolean specifying whether the FIND_LIBRARY " |
|---|
| 3371 |
"command should find shared libraries with OpenBSD-style versioned " |
|---|
| 3372 |
"extension: \".so.<major>.<minor>\". " |
|---|
| 3373 |
"The property is set to true on OpenBSD and false on other platforms."); |
|---|
| 3374 |
cm->DefineProperty |
|---|
| 3375 |
("ENABLED_FEATURES", cmProperty::GLOBAL, |
|---|
| 3376 |
"List of features which are enabled during the CMake run.", |
|---|
| 3377 |
"List of features which are enabled during the CMake run. Be default " |
|---|
| 3378 |
"it contains the names of all packages which were found. This is " |
|---|
| 3379 |
"determined using the <NAME>_FOUND variables. Packages which are " |
|---|
| 3380 |
"searched QUIET are not listed. A project can add its own features to " |
|---|
| 3381 |
"this list.This property is used by the macros in FeatureSummary.cmake."); |
|---|
| 3382 |
cm->DefineProperty |
|---|
| 3383 |
("DISABLED_FEATURES", cmProperty::GLOBAL, |
|---|
| 3384 |
"List of features which are disabled during the CMake run.", |
|---|
| 3385 |
"List of features which are disabled during the CMake run. Be default " |
|---|
| 3386 |
"it contains the names of all packages which were not found. This is " |
|---|
| 3387 |
"determined using the <NAME>_FOUND variables. Packages which are " |
|---|
| 3388 |
"searched QUIET are not listed. A project can add its own features to " |
|---|
| 3389 |
"this list.This property is used by the macros in FeatureSummary.cmake."); |
|---|
| 3390 |
cm->DefineProperty |
|---|
| 3391 |
("PACKAGES_FOUND", cmProperty::GLOBAL, |
|---|
| 3392 |
"List of packages which were found during the CMake run.", |
|---|
| 3393 |
"List of packages which were found during the CMake run. Whether a " |
|---|
| 3394 |
"package has been found is determined using the <NAME>_FOUND variables."); |
|---|
| 3395 |
cm->DefineProperty |
|---|
| 3396 |
("PACKAGES_NOT_FOUND", cmProperty::GLOBAL, |
|---|
| 3397 |
"List of packages which were not found during the CMake run.", |
|---|
| 3398 |
"List of packages which were not found during the CMake run. Whether a " |
|---|
| 3399 |
"package has been found is determined using the <NAME>_FOUND variables."); |
|---|
| 3400 |
|
|---|
| 3401 |
cm->DefineProperty( |
|---|
| 3402 |
"__CMAKE_DELETE_CACHE_CHANGE_VARS_", cmProperty::GLOBAL, |
|---|
| 3403 |
"Internal property", |
|---|
| 3404 |
"Used to detect compiler changes, Do not set."); |
|---|
| 3405 |
|
|---|
| 3406 |
cm->DefineProperty( |
|---|
| 3407 |
"DEBUG_CONFIGURATIONS", cmProperty::GLOBAL, |
|---|
| 3408 |
"Specify which configurations are for debugging.", |
|---|
| 3409 |
"The value must be a semi-colon separated list of configuration names. " |
|---|
| 3410 |
"Currently this property is used only by the target_link_libraries " |
|---|
| 3411 |
"command (see its documentation for details). " |
|---|
| 3412 |
"Additional uses may be defined in the future. " |
|---|
| 3413 |
"\n" |
|---|
| 3414 |
"This property must be set at the top level of the project and before " |
|---|
| 3415 |
"the first target_link_libraries command invocation. " |
|---|
| 3416 |
"If any entry in the list does not match a valid configuration for " |
|---|
| 3417 |
"the project the behavior is undefined."); |
|---|
| 3418 |
|
|---|
| 3419 |
cm->DefineProperty( |
|---|
| 3420 |
"GLOBAL_DEPENDS_DEBUG_MODE", cmProperty::GLOBAL, |
|---|
| 3421 |
"Enable global target dependency graph debug mode.", |
|---|
| 3422 |
"CMake automatically analyzes the global inter-target dependency graph " |
|---|
| 3423 |
"at the beginning of native build system generation. " |
|---|
| 3424 |
"This property causes it to display details of its analysis to stderr."); |
|---|
| 3425 |
|
|---|
| 3426 |
cm->DefineProperty( |
|---|
| 3427 |
"GLOBAL_DEPENDS_NO_CYCLES", cmProperty::GLOBAL, |
|---|
| 3428 |
"Disallow global target dependency graph cycles.", |
|---|
| 3429 |
"CMake automatically analyzes the global inter-target dependency graph " |
|---|
| 3430 |
"at the beginning of native build system generation. " |
|---|
| 3431 |
"It reports an error if the dependency graph contains a cycle that " |
|---|
| 3432 |
"does not consist of all STATIC library targets. " |
|---|
| 3433 |
"This property tells CMake to disallow all cycles completely, even " |
|---|
| 3434 |
"among static libraries."); |
|---|
| 3435 |
|
|---|
| 3436 |
cm->DefineProperty( |
|---|
| 3437 |
"ALLOW_DUPLICATE_CUSTOM_TARGETS", cmProperty::GLOBAL, |
|---|
| 3438 |
"Allow duplicate custom targets to be created.", |
|---|
| 3439 |
"Normally CMake requires that all targets built in a project have " |
|---|
| 3440 |
"globally unique logical names (see policy CMP0002). " |
|---|
| 3441 |
"This is necessary to generate meaningful project file names in " |
|---|
| 3442 |
"Xcode and VS IDE generators. " |
|---|
| 3443 |
"It also allows the target names to be referenced unambiguously.\n" |
|---|
| 3444 |
"Makefile generators are capable of supporting duplicate custom target " |
|---|
| 3445 |
"names. " |
|---|
| 3446 |
"For projects that care only about Makefile generators and do " |
|---|
| 3447 |
"not wish to support Xcode or VS IDE generators, one may set this " |
|---|
| 3448 |
"property to true to allow duplicate custom targets. " |
|---|
| 3449 |
"The property allows multiple add_custom_target command calls in " |
|---|
| 3450 |
"different directories to specify the same target name. " |
|---|
| 3451 |
"However, setting this property will cause non-Makefile generators " |
|---|
| 3452 |
"to produce an error and refuse to generate the project." |
|---|
| 3453 |
); |
|---|
| 3454 |
|
|---|
| 3455 |
cm->DefineProperty |
|---|
| 3456 |
("IN_TRY_COMPILE", cmProperty::GLOBAL, |
|---|
| 3457 |
"Read-only property that is true during a try-compile configuration.", |
|---|
| 3458 |
"True when building a project inside a TRY_COMPILE or TRY_RUN command."); |
|---|
| 3459 |
cm->DefineProperty |
|---|
| 3460 |
("ENABLED_LANGUAGES", cmProperty::GLOBAL, |
|---|
| 3461 |
"Read-only property that contains the list of currently " |
|---|
| 3462 |
"enabled languages", |
|---|
| 3463 |
"Set to list of currently enabled languages."); |
|---|
| 3464 |
|
|---|
| 3465 |
cm->DefineProperty |
|---|
| 3466 |
("RULE_LAUNCH_COMPILE", cmProperty::GLOBAL, |
|---|
| 3467 |
"Specify a launcher for compile rules.", |
|---|
| 3468 |
"Makefile generators prefix compiler commands with the given " |
|---|
| 3469 |
"launcher command line. " |
|---|
| 3470 |
"This is intended to allow launchers to intercept build problems " |
|---|
| 3471 |
"with high granularity. " |
|---|
| 3472 |
"Non-Makefile generators currently ignore this property."); |
|---|
| 3473 |
cm->DefineProperty |
|---|
| 3474 |
("RULE_LAUNCH_LINK", cmProperty::GLOBAL, |
|---|
| 3475 |
"Specify a launcher for link rules.", |
|---|
| 3476 |
"Makefile generators prefix link and archive commands with the given " |
|---|
| 3477 |
"launcher command line. " |
|---|
| 3478 |
"This is intended to allow launchers to intercept build problems " |
|---|
| 3479 |
"with high granularity. " |
|---|
| 3480 |
"Non-Makefile generators currently ignore this property."); |
|---|
| 3481 |
cm->DefineProperty |
|---|
| 3482 |
("RULE_LAUNCH_CUSTOM", cmProperty::GLOBAL, |
|---|
| 3483 |
"Specify a launcher for custom rules.", |
|---|
| 3484 |
"Makefile generators prefix custom commands with the given " |
|---|
| 3485 |
"launcher command line. " |
|---|
| 3486 |
"This is intended to allow launchers to intercept build problems " |
|---|
| 3487 |
"with high granularity. " |
|---|
| 3488 |
"Non-Makefile generators currently ignore this property."); |
|---|
| 3489 |
|
|---|
| 3490 |
cm->DefineProperty |
|---|
| 3491 |
("RULE_MESSAGES", cmProperty::GLOBAL, |
|---|
| 3492 |
"Specify whether to report a message for each make rule.", |
|---|
| 3493 |
"This property specifies whether Makefile generators should add a " |
|---|
| 3494 |
"progress message describing what each build rule does. " |
|---|
| 3495 |
"If the property is not set the default is ON. " |
|---|
| 3496 |
"Set the property to OFF to disable granular messages and report only " |
|---|
| 3497 |
"as each target completes. " |
|---|
| 3498 |
"This is intended to allow scripted builds to avoid the build time " |
|---|
| 3499 |
"cost of detailed reports. " |
|---|
| 3500 |
"If a CMAKE_RULE_MESSAGES cache entry exists its value initializes " |
|---|
| 3501 |
"the value of this property. " |
|---|
| 3502 |
"Non-Makefile generators currently ignore this property."); |
|---|
| 3503 |
|
|---|
| 3504 |
// ================================================================ |
|---|
| 3505 |
// define variables as well |
|---|
| 3506 |
// ================================================================ |
|---|
| 3507 |
cmDocumentVariables::DefineVariables(cm); |
|---|
| 3508 |
} |
|---|
| 3509 |
|
|---|
| 3510 |
|
|---|
| 3511 |
void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope, |
|---|
| 3512 |
const char *ShortDescription, |
|---|
| 3513 |
const char *FullDescription, |
|---|
| 3514 |
bool chained, const char *docSection) |
|---|
| 3515 |
{ |
|---|
| 3516 |
this->PropertyDefinitions[scope].DefineProperty(name,scope,ShortDescription, |
|---|
| 3517 |
FullDescription, |
|---|
| 3518 |
docSection, |
|---|
| 3519 |
chained); |
|---|
| 3520 |
} |
|---|
| 3521 |
|
|---|
| 3522 |
cmPropertyDefinition *cmake |
|---|
| 3523 |
::GetPropertyDefinition(const char *name, |
|---|
| 3524 |
cmProperty::ScopeType scope) |
|---|
| 3525 |
{ |
|---|
| 3526 |
if (this->IsPropertyDefined(name,scope)) |
|---|
| 3527 |
{ |
|---|
| 3528 |
return &(this->PropertyDefinitions[scope][name]); |
|---|
| 3529 |
} |
|---|
| 3530 |
return 0; |
|---|
| 3531 |
} |
|---|
| 3532 |
|
|---|
| 3533 |
void cmake::RecordPropertyAccess(const char *name, |
|---|
| 3534 |
cmProperty::ScopeType scope) |
|---|
| 3535 |
{ |
|---|
| 3536 |
this->AccessedProperties.insert |
|---|
| 3537 |
(std::pair<cmStdString,cmProperty::ScopeType>(name,scope)); |
|---|
| 3538 |
} |
|---|
| 3539 |
|
|---|
| 3540 |
void cmake::ReportUndefinedPropertyAccesses(const char *filename) |
|---|
| 3541 |
{ |
|---|
| 3542 |
FILE *progFile = fopen(filename,"w"); |
|---|
| 3543 |
if (!progFile || !this->GlobalGenerator) |
|---|
| 3544 |
{ |
|---|
| 3545 |
return; |
|---|
| 3546 |
} |
|---|
| 3547 |
|
|---|
| 3548 |
// what are the enabled languages? |
|---|
| 3549 |
std::vector<std::string> enLangs; |
|---|
| 3550 |
this->GlobalGenerator->GetEnabledLanguages(enLangs); |
|---|
| 3551 |
|
|---|
| 3552 |
// Common configuration names. |
|---|
| 3553 |
// TODO: Compute current configuration(s). |
|---|
| 3554 |
std::vector<std::string> enConfigs; |
|---|
| 3555 |
enConfigs.push_back(""); |
|---|
| 3556 |
enConfigs.push_back("DEBUG"); |
|---|
| 3557 |
enConfigs.push_back("RELEASE"); |
|---|
| 3558 |
enConfigs.push_back("MINSIZEREL"); |
|---|
| 3559 |
enConfigs.push_back("RELWITHDEBINFO"); |
|---|
| 3560 |
|
|---|
| 3561 |
// take all the defined properties and add definitions for all the enabled |
|---|
| 3562 |
// languages |
|---|
| 3563 |
std::set<std::pair<cmStdString,cmProperty::ScopeType> > aliasedProperties; |
|---|
| 3564 |
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::iterator i; |
|---|
| 3565 |
i = this->PropertyDefinitions.begin(); |
|---|
| 3566 |
for (;i != this->PropertyDefinitions.end(); ++i) |
|---|
| 3567 |
{ |
|---|
| 3568 |
cmPropertyDefinitionMap::iterator j; |
|---|
| 3569 |
for (j = i->second.begin(); j != i->second.end(); ++j) |
|---|
| 3570 |
{ |
|---|
| 3571 |
// TODO: What if both <LANG> and <CONFIG> appear? |
|---|
| 3572 |
if (j->first.find("<CONFIG>") != std::string::npos) |
|---|
| 3573 |
{ |
|---|
| 3574 |
std::vector<std::string>::const_iterator k; |
|---|
| 3575 |
for (k = enConfigs.begin(); k != enConfigs.end(); ++k) |
|---|
| 3576 |
{ |
|---|
| 3577 |
std::string tmp = j->first; |
|---|
| 3578 |
cmSystemTools::ReplaceString(tmp, "<CONFIG>", k->c_str()); |
|---|
| 3579 |
// add alias |
|---|
| 3580 |
aliasedProperties.insert |
|---|
| 3581 |
(std::pair<cmStdString,cmProperty::ScopeType>(tmp,i->first)); |
|---|
| 3582 |
} |
|---|
| 3583 |
} |
|---|
| 3584 |
if (j->first.find("<LANG>") != std::string::npos) |
|---|
| 3585 |
{ |
|---|
| 3586 |
std::vector<std::string>::const_iterator k; |
|---|
| 3587 |
for (k = enLangs.begin(); k != enLangs.end(); ++k) |
|---|
| 3588 |
{ |
|---|
| 3589 |
std::string tmp = j->first; |
|---|
| 3590 |
cmSystemTools::ReplaceString(tmp, "<LANG>", k->c_str()); |
|---|
| 3591 |
// add alias |
|---|
| 3592 |
aliasedProperties.insert |
|---|
| 3593 |
(std::pair<cmStdString,cmProperty::ScopeType>(tmp,i->first)); |
|---|
| 3594 |
} |
|---|
| 3595 |
} |
|---|
| 3596 |
} |
|---|
| 3597 |
} |
|---|
| 3598 |
|
|---|
| 3599 |
std::set<std::pair<cmStdString,cmProperty::ScopeType> >::const_iterator ap; |
|---|
| 3600 |
ap = this->AccessedProperties.begin(); |
|---|
| 3601 |
for (;ap != this->AccessedProperties.end(); ++ap) |
|---|
| 3602 |
{ |
|---|
| 3603 |
if (!this->IsPropertyDefined(ap->first.c_str(),ap->second) && |
|---|
| 3604 |
aliasedProperties.find(std::pair<cmStdString,cmProperty::ScopeType> |
|---|
| 3605 |
(ap->first,ap->second)) == |
|---|
| 3606 |
aliasedProperties.end()) |
|---|
| 3607 |
{ |
|---|
| 3608 |
const char *scopeStr = ""; |
|---|
| 3609 |
switch (ap->second) |
|---|
| 3610 |
{ |
|---|
| 3611 |
case cmProperty::TARGET: |
|---|
| 3612 |
scopeStr = "TARGET"; |
|---|
| 3613 |
break; |
|---|
| 3614 |
case cmProperty::SOURCE_FILE: |
|---|
| 3615 |
scopeStr = "SOURCE_FILE"; |
|---|
| 3616 |
break; |
|---|
| 3617 |
case cmProperty::DIRECTORY: |
|---|
| 3618 |
scopeStr = "DIRECTORY"; |
|---|
| 3619 |
break; |
|---|
| 3620 |
case cmProperty::TEST: |
|---|
| 3621 |
scopeStr = "TEST"; |
|---|
| 3622 |
break; |
|---|
| 3623 |
case cmProperty::VARIABLE: |
|---|
| 3624 |
scopeStr = "VARIABLE"; |
|---|
| 3625 |
break; |
|---|
| 3626 |
case cmProperty::CACHED_VARIABLE: |
|---|
| 3627 |
scopeStr = "CACHED_VARIABLE"; |
|---|
| 3628 |
break; |
|---|
| 3629 |
default: |
|---|
| 3630 |
scopeStr = "unknown"; |
|---|
| 3631 |
break; |
|---|
| 3632 |
} |
|---|
| 3633 |
fprintf(progFile, "%s with scope %s\n", ap->first.c_str(), scopeStr); |
|---|
| 3634 |
} |
|---|
| 3635 |
} |
|---|
| 3636 |
fclose(progFile); |
|---|
| 3637 |
} |
|---|
| 3638 |
|
|---|
| 3639 |
bool cmake::IsPropertyDefined(const char *name, cmProperty::ScopeType scope) |
|---|
| 3640 |
{ |
|---|
| 3641 |
return this->PropertyDefinitions[scope].IsPropertyDefined(name); |
|---|
| 3642 |
} |
|---|
| 3643 |
|
|---|
| 3644 |
bool cmake::IsPropertyChained(const char *name, cmProperty::ScopeType scope) |
|---|
| 3645 |
{ |
|---|
| 3646 |
return this->PropertyDefinitions[scope].IsPropertyChained(name); |
|---|
| 3647 |
} |
|---|
| 3648 |
|
|---|
| 3649 |
void cmake::SetProperty(const char* prop, const char* value) |
|---|
| 3650 |
{ |
|---|
| 3651 |
if (!prop) |
|---|
| 3652 |
{ |
|---|
| 3653 |
return; |
|---|
| 3654 |
} |
|---|
| 3655 |
|
|---|
| 3656 |
// Special hook to invalidate cached value. |
|---|
| 3657 |
if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0) |
|---|
| 3658 |
{ |
|---|
| 3659 |
this->DebugConfigs.clear(); |
|---|
| 3660 |
} |
|---|
| 3661 |
|
|---|
| 3662 |
this->Properties.SetProperty(prop, value, cmProperty::GLOBAL); |
|---|
| 3663 |
} |
|---|
| 3664 |
|
|---|
| 3665 |
void cmake::AppendProperty(const char* prop, const char* value) |
|---|
| 3666 |
{ |
|---|
| 3667 |
if (!prop) |
|---|
| 3668 |
{ |
|---|
| 3669 |
return; |
|---|
| 3670 |
} |
|---|
| 3671 |
|
|---|
| 3672 |
// Special hook to invalidate cached value. |
|---|
| 3673 |
if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0) |
|---|
| 3674 |
{ |
|---|
| 3675 |
this->DebugConfigs.clear(); |
|---|
| 3676 |
} |
|---|
| 3677 |
|
|---|
| 3678 |
this->Properties.AppendProperty(prop, value, cmProperty::GLOBAL); |
|---|
| 3679 |
} |
|---|
| 3680 |
|
|---|
| 3681 |
const char *cmake::GetProperty(const char* prop) |
|---|
| 3682 |
{ |
|---|
| 3683 |
return this->GetProperty(prop, cmProperty::GLOBAL); |
|---|
| 3684 |
} |
|---|
| 3685 |
|
|---|
| 3686 |
const char *cmake::GetProperty(const char* prop, cmProperty::ScopeType scope) |
|---|
| 3687 |
{ |
|---|
| 3688 |
if(!prop) |
|---|
| 3689 |
{ |
|---|
| 3690 |
return 0; |
|---|
| 3691 |
} |
|---|
| 3692 |
bool chain = false; |
|---|
| 3693 |
|
|---|
| 3694 |
// watch for special properties |
|---|
| 3695 |
std::string propname = prop; |
|---|
| 3696 |
std::string output = ""; |
|---|
| 3697 |
if ( propname == "CACHE_VARIABLES" ) |
|---|
| 3698 |
{ |
|---|
| 3699 |
cmCacheManager::CacheIterator cit = |
|---|
| 3700 |
this->GetCacheManager()->GetCacheIterator(); |
|---|
| 3701 |
for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() ) |
|---|
| 3702 |
{ |
|---|
| 3703 |
if ( output.size() ) |
|---|
| 3704 |
{ |
|---|
| 3705 |
output += ";"; |
|---|
| 3706 |
} |
|---|
| 3707 |
output += cit.GetName(); |
|---|
| 3708 |
} |
|---|
| 3709 |
this->SetProperty("CACHE_VARIABLES", output.c_str()); |
|---|
| 3710 |
} |
|---|
| 3711 |
else if ( propname == "COMMANDS" ) |
|---|
| 3712 |
{ |
|---|
| 3713 |
cmake::RegisteredCommandsMap::iterator cmds |
|---|
| 3714 |
= this->GetCommands()->begin(); |
|---|
| 3715 |
for (unsigned int cc=0 ; cmds != this->GetCommands()->end(); ++ cmds ) |
|---|
| 3716 |
{ |
|---|
| 3717 |
if ( cc > 0 ) |
|---|
| 3718 |
{ |
|---|
| 3719 |
output += ";"; |
|---|
| 3720 |
} |
|---|
| 3721 |
output += cmds->first.c_str(); |
|---|
| 3722 |
cc++; |
|---|
| 3723 |
} |
|---|
| 3724 |
this->SetProperty("COMMANDS",output.c_str()); |
|---|
| 3725 |
} |
|---|
| 3726 |
else if ( propname == "IN_TRY_COMPILE" ) |
|---|
| 3727 |
{ |
|---|
| 3728 |
this->SetProperty("IN_TRY_COMPILE", |
|---|
| 3729 |
this->GetIsInTryCompile()? "1":"0"); |
|---|
| 3730 |
} |
|---|
| 3731 |
else if ( propname == "ENABLED_LANGUAGES" ) |
|---|
| 3732 |
{ |
|---|
| 3733 |
std::string lang; |
|---|
| 3734 |
if(this->GlobalGenerator) |
|---|
| 3735 |
{ |
|---|
| 3736 |
std::vector<std::string> enLangs; |
|---|
| 3737 |
this->GlobalGenerator->GetEnabledLanguages(enLangs); |
|---|
| 3738 |
const char* sep = ""; |
|---|
| 3739 |
for(std::vector<std::string>::iterator i = enLangs.begin(); |
|---|
| 3740 |
i != enLangs.end(); ++i) |
|---|
| 3741 |
{ |
|---|
| 3742 |
lang += sep; |
|---|
| 3743 |
sep = ";"; |
|---|
| 3744 |
lang += *i; |
|---|
| 3745 |
} |
|---|
| 3746 |
} |
|---|
| 3747 |
this->SetProperty("ENABLED_LANGUAGES", lang.c_str()); |
|---|
| 3748 |
} |
|---|
| 3749 |
return this->Properties.GetPropertyValue(prop, scope, chain); |
|---|
| 3750 |
} |
|---|
| 3751 |
|
|---|
| 3752 |
bool cmake::GetPropertyAsBool(const char* prop) |
|---|
| 3753 |
{ |
|---|
| 3754 |
return cmSystemTools::IsOn(this->GetProperty(prop)); |
|---|
| 3755 |
} |
|---|
| 3756 |
|
|---|
| 3757 |
int cmake::GetSystemInformation(std::vector<std::string>& args) |
|---|
| 3758 |
{ |
|---|
| 3759 |
// so create the directory |
|---|
| 3760 |
std::string resultFile; |
|---|
| 3761 |
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); |
|---|
| 3762 |
std::string destPath = cwd + "/__cmake_systeminformation"; |
|---|
| 3763 |
cmSystemTools::RemoveADirectory(destPath.c_str()); |
|---|
| 3764 |
if (!cmSystemTools::MakeDirectory(destPath.c_str())) |
|---|
| 3765 |
{ |
|---|
| 3766 |
std::cerr << "Error: --system-information must be run from a " |
|---|
| 3767 |
"writable directory!\n"; |
|---|
| 3768 |
return 1; |
|---|
| 3769 |
} |
|---|
| 3770 |
|
|---|
| 3771 |
// process the arguments |
|---|
| 3772 |
bool writeToStdout = true; |
|---|
| 3773 |
for(unsigned int i=1; i < args.size(); ++i) |
|---|
| 3774 |
{ |
|---|
| 3775 |
std::string arg = args[i]; |
|---|
| 3776 |
if(arg.find("-V",0) == 0) |
|---|
| 3777 |
{ |
|---|
| 3778 |
this->Verbose = true; |
|---|
| 3779 |
} |
|---|
| 3780 |
else if(arg.find("-G",0) == 0) |
|---|
| 3781 |
{ |
|---|
| 3782 |
std::string value = arg.substr(2); |
|---|
| 3783 |
if(value.size() == 0) |
|---|
| 3784 |
{ |
|---|
| 3785 |
++i; |
|---|
| 3786 |
if(i >= args.size()) |
|---|
| 3787 |
{ |
|---|
| 3788 |
cmSystemTools::Error("No generator specified for -G"); |
|---|
| 3789 |
return -1; |
|---|
| 3790 |
} |
|---|
| 3791 |
value = args[i]; |
|---|
| 3792 |
} |
|---|
| 3793 |
cmGlobalGenerator* gen = |
|---|
| 3794 |
this->CreateGlobalGenerator(value.c_str()); |
|---|
| 3795 |
if(!gen) |
|---|
| 3796 |
{ |
|---|
| 3797 |
cmSystemTools::Error("Could not create named generator ", |
|---|
| 3798 |
value.c_str()); |
|---|
| 3799 |
} |
|---|
| 3800 |
else |
|---|
| 3801 |
{ |
|---|
| 3802 |
this->SetGlobalGenerator(gen); |
|---|
| 3803 |
} |
|---|
| 3804 |
} |
|---|
| 3805 |
// no option assume it is the output file |
|---|
| 3806 |
else |
|---|
| 3807 |
{ |
|---|
| 3808 |
if (!cmSystemTools::FileIsFullPath(arg.c_str())) |
|---|
| 3809 |
{ |
|---|
| 3810 |
resultFile = cwd; |
|---|
| 3811 |
resultFile += "/"; |
|---|
| 3812 |
} |
|---|
| 3813 |
resultFile += arg; |
|---|
| 3814 |
writeToStdout = false; |
|---|
| 3815 |
} |
|---|
| 3816 |
} |
|---|
| 3817 |
|
|---|
| 3818 |
|
|---|
| 3819 |
// we have to find the module directory, so we can copy the files |
|---|
| 3820 |
this->AddCMakePaths(); |
|---|
| 3821 |
std::string modulesPath = |
|---|
| 3822 |
this->CacheManager->GetCacheValue("CMAKE_ROOT"); |
|---|
| 3823 |
modulesPath += "/Modules"; |
|---|
| 3824 |
std::string inFile = modulesPath; |
|---|
| 3825 |
inFile += "/SystemInformation.cmake"; |
|---|
| 3826 |
std::string outFile = destPath; |
|---|
| 3827 |
outFile += "/CMakeLists.txt"; |
|---|
| 3828 |
|
|---|
| 3829 |
// Copy file |
|---|
| 3830 |
if(!cmSystemTools::cmCopyFile(inFile.c_str(), outFile.c_str())) |
|---|
| 3831 |
{ |
|---|
| 3832 |
std::cerr << "Error copying file \"" << inFile.c_str() |
|---|
| 3833 |
<< "\" to \"" << outFile.c_str() << "\".\n"; |
|---|
| 3834 |
return 1; |
|---|
| 3835 |
} |
|---|
| 3836 |
|
|---|
| 3837 |
// do we write to a file or to stdout? |
|---|
| 3838 |
if (resultFile.size() == 0) |
|---|
| 3839 |
{ |
|---|
| 3840 |
resultFile = cwd; |
|---|
| 3841 |
resultFile += "/__cmake_systeminformation/results.txt"; |
|---|
| 3842 |
} |
|---|
| 3843 |
|
|---|
| 3844 |
// now run cmake on the CMakeLists file |
|---|
| 3845 |
cmSystemTools::ChangeDirectory(destPath.c_str()); |
|---|
| 3846 |
std::vector<std::string> args2; |
|---|
| 3847 |
args2.push_back(args[0]); |
|---|
| 3848 |
args2.push_back(destPath); |
|---|
| 3849 |
std::string resultArg = "-DRESULT_FILE="; |
|---|
| 3850 |
resultArg += resultFile; |
|---|
| 3851 |
args2.push_back(resultArg); |
|---|
| 3852 |
int res = this->Run(args2, false); |
|---|
| 3853 |
|
|---|
| 3854 |
if (res != 0) |
|---|
| 3855 |
{ |
|---|
| 3856 |
std::cerr << "Error: --system-information failed on internal CMake!\n"; |
|---|
| 3857 |
return res; |
|---|
| 3858 |
} |
|---|
| 3859 |
|
|---|
| 3860 |
// change back to the original directory |
|---|
| 3861 |
cmSystemTools::ChangeDirectory(cwd.c_str()); |
|---|
| 3862 |
|
|---|
| 3863 |
// echo results to stdout if needed |
|---|
| 3864 |
if (writeToStdout) |
|---|
| 3865 |
{ |
|---|
| 3866 |
FILE* fin = fopen(resultFile.c_str(), "r"); |
|---|
| 3867 |
if(fin) |
|---|
| 3868 |
{ |
|---|
| 3869 |
const int bufferSize = 4096; |
|---|
| 3870 |
char buffer[bufferSize]; |
|---|
| 3871 |
size_t n; |
|---|
| 3872 |
while((n = fread(buffer, 1, bufferSize, fin)) > 0) |
|---|
| 3873 |
{ |
|---|
| 3874 |
for(char* c = buffer; c < buffer+n; ++c) |
|---|
| 3875 |
{ |
|---|
| 3876 |
putc(*c, stdout); |
|---|
| 3877 |
} |
|---|
| 3878 |
fflush(stdout); |
|---|
| 3879 |
} |
|---|
| 3880 |
fclose(fin); |
|---|
| 3881 |
} |
|---|
| 3882 |
} |
|---|
| 3883 |
|
|---|
| 3884 |
// clean up the directory |
|---|
| 3885 |
cmSystemTools::RemoveADirectory(destPath.c_str()); |
|---|
| 3886 |
return 0; |
|---|
| 3887 |
} |
|---|
| 3888 |
|
|---|
| 3889 |
//---------------------------------------------------------------------------- |
|---|
| 3890 |
static bool cmakeCheckStampFile(const char* stampName) |
|---|
| 3891 |
{ |
|---|
| 3892 |
// The stamp file does not exist. Use the stamp dependencies to |
|---|
| 3893 |
// determine whether it is really out of date. This works in |
|---|
| 3894 |
// conjunction with cmLocalVisualStudio7Generator to avoid |
|---|
| 3895 |
// repeatedly re-running CMake when the user rebuilds the entire |
|---|
| 3896 |
// solution. |
|---|
| 3897 |
std::string stampDepends = stampName; |
|---|
| 3898 |
stampDepends += ".depend"; |
|---|
| 3899 |
#if defined(_WIN32) || defined(__CYGWIN__) |
|---|
| 3900 |
std::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary); |
|---|
| 3901 |
#else |
|---|
| 3902 |
std::ifstream fin(stampDepends.c_str(), std::ios::in); |
|---|
| 3903 |
#endif |
|---|
| 3904 |
if(!fin) |
|---|
| 3905 |
{ |
|---|
| 3906 |
// The stamp dependencies file cannot be read. Just assume the |
|---|
| 3907 |
// build system is really out of date. |
|---|
| 3908 |
std::cout << "CMake is re-running because " << stampName |
|---|
| 3909 |
<< " dependency file is missing.\n"; |
|---|
| 3910 |
return false; |
|---|
| 3911 |
} |
|---|
| 3912 |
|
|---|
| 3913 |
// Compare the stamp dependencies against the dependency file itself. |
|---|
| 3914 |
cmFileTimeComparison ftc; |
|---|
| 3915 |
std::string dep; |
|---|
| 3916 |
while(cmSystemTools::GetLineFromStream(fin, dep)) |
|---|
| 3917 |
{ |
|---|
| 3918 |
int result; |
|---|
| 3919 |
if(dep.length() >= 1 && dep[0] != '#' && |
|---|
| 3920 |
(!ftc.FileTimeCompare(stampDepends.c_str(), dep.c_str(), &result) |
|---|
| 3921 |
|| result < 0)) |
|---|
| 3922 |
{ |
|---|
| 3923 |
// The stamp depends file is older than this dependency. The |
|---|
| 3924 |
// build system is really out of date. |
|---|
| 3925 |
std::cout << "CMake is re-running because " << stampName |
|---|
| 3926 |
<< " is out-of-date.\n"; |
|---|
| 3927 |
return false; |
|---|
| 3928 |
} |
|---|
| 3929 |
} |
|---|
| 3930 |
|
|---|
| 3931 |
// The build system is up to date. The stamp file has been removed |
|---|
| 3932 |
// by the VS IDE due to a "rebuild" request. Just restore it. |
|---|
| 3933 |
std::ofstream stamp(stampName); |
|---|
| 3934 |
stamp << "# CMake generation timestamp file this directory.\n"; |
|---|
| 3935 |
if(stamp) |
|---|
| 3936 |
{ |
|---|
| 3937 |
// Notify the user why CMake is not re-running. It is safe to |
|---|
| 3938 |
// just print to stdout here because this code is only reachable |
|---|
| 3939 |
// through an undocumented flag used by the VS generator. |
|---|
| 3940 |
std::cout << "CMake does not need to re-run because " |
|---|
| 3941 |
<< stampName << " is up-to-date.\n"; |
|---|
| 3942 |
return true; |
|---|
| 3943 |
} |
|---|
| 3944 |
else |
|---|
| 3945 |
{ |
|---|
| 3946 |
cmSystemTools::Error("Cannot restore timestamp ", stampName); |
|---|
| 3947 |
return false; |
|---|
| 3948 |
} |
|---|
| 3949 |
} |
|---|
| 3950 |
|
|---|
| 3951 |
//---------------------------------------------------------------------------- |
|---|
| 3952 |
static bool cmakeCheckStampList(const char* stampList) |
|---|
| 3953 |
{ |
|---|
| 3954 |
// If the stamp list does not exist CMake must rerun to generate it. |
|---|
| 3955 |
if(!cmSystemTools::FileExists(stampList)) |
|---|
| 3956 |
{ |
|---|
| 3957 |
std::cout << "CMake is re-running because generate.stamp.list " |
|---|
| 3958 |
<< "is missing.\n"; |
|---|
| 3959 |
return false; |
|---|
| 3960 |
} |
|---|
| 3961 |
std::ifstream fin(stampList); |
|---|
| 3962 |
if(!fin) |
|---|
| 3963 |
{ |
|---|
| 3964 |
std::cout << "CMake is re-running because generate.stamp.list " |
|---|
| 3965 |
<< "could not be read.\n"; |
|---|
| 3966 |
return false; |
|---|
| 3967 |
} |
|---|
| 3968 |
|
|---|
| 3969 |
// Check each stamp. |
|---|
| 3970 |
std::string stampName; |
|---|
| 3971 |
while(cmSystemTools::GetLineFromStream(fin, stampName)) |
|---|
| 3972 |
{ |
|---|
| 3973 |
if(!cmakeCheckStampFile(stampName.c_str())) |
|---|
| 3974 |
{ |
|---|
| 3975 |
return false; |
|---|
| 3976 |
} |
|---|
| 3977 |
} |
|---|
| 3978 |
return true; |
|---|
| 3979 |
} |
|---|
| 3980 |
|
|---|
| 3981 |
// For visual studio 2005 and newer manifest files need to be embeded into |
|---|
| 3982 |
// exe and dll's. This code does that in such a way that incremental linking |
|---|
| 3983 |
// still works. |
|---|
| 3984 |
int cmake::VisualStudioLink(std::vector<std::string>& args, int type) |
|---|
| 3985 |
{ |
|---|
| 3986 |
if(args.size() < 2) |
|---|
| 3987 |
{ |
|---|
| 3988 |
return -1; |
|---|
| 3989 |
} |
|---|
| 3990 |
bool verbose = false; |
|---|
| 3991 |
if(cmSystemTools::GetEnv("VERBOSE")) |
|---|
| 3992 |
{ |
|---|
| 3993 |
verbose = true; |
|---|
| 3994 |
} |
|---|
| 3995 |
std::vector<std::string> expandedArgs; |
|---|
| 3996 |
for(std::vector<std::string>::iterator i = args.begin(); |
|---|
| 3997 |
i != args.end(); ++i) |
|---|
| 3998 |
{ |
|---|
| 3999 |
// check for nmake temporary files |
|---|
| 4000 |
if((*i)[0] == '@' && i->find("@CMakeFiles") != 0 ) |
|---|
| 4001 |
{ |
|---|
| 4002 |
std::ifstream fin(i->substr(1).c_str()); |
|---|
| 4003 |
std::string line; |
|---|
| 4004 |
while(cmSystemTools::GetLineFromStream(fin, |
|---|
| 4005 |
line)) |
|---|
| 4006 |
{ |
|---|
| 4007 |
cmSystemTools::ParseWindowsCommandLine(line.c_str(), expandedArgs); |
|---|
| 4008 |
} |
|---|
| 4009 |
} |
|---|
| 4010 |
else |
|---|
| 4011 |
{ |
|---|
| 4012 |
expandedArgs.push_back(*i); |
|---|
| 4013 |
} |
|---|
| 4014 |
} |
|---|
| 4015 |
bool hasIncremental = false; |
|---|
| 4016 |
bool hasManifest = true; |
|---|
| 4017 |
for(std::vector<std::string>::iterator i = expandedArgs.begin(); |
|---|
| 4018 |
i != expandedArgs.end(); ++i) |
|---|
| 4019 |
{ |
|---|
| 4020 |
if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL:YES") == 0) |
|---|
| 4021 |
{ |
|---|
| 4022 |
hasIncremental = true; |
|---|
| 4023 |
} |
|---|
| 4024 |
if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0) |
|---|
| 4025 |
{ |
|---|
| 4026 |
hasManifest = false; |
|---|
| 4027 |
} |
|---|
| 4028 |
} |
|---|
| 4029 |
if(hasIncremental && hasManifest) |
|---|
| 4030 |
{ |
|---|
| 4031 |
if(verbose) |
|---|
| 4032 |
{ |
|---|
| 4033 |
std::cout << "Visual Studio Incremental Link with embeded manifests\n"; |
|---|
| 4034 |
} |
|---|
| 4035 |
return cmake::VisualStudioLinkIncremental(expandedArgs, type, verbose); |
|---|
| 4036 |
} |
|---|
| 4037 |
if(verbose) |
|---|
| 4038 |
{ |
|---|
| 4039 |
if(!hasIncremental) |
|---|
| 4040 |
{ |
|---|
| 4041 |
std::cout << "Visual Studio Non-Incremental Link\n"; |
|---|
| 4042 |
} |
|---|
| 4043 |
else |
|---|
| 4044 |
{ |
|---|
| 4045 |
std::cout << "Visual Studio Incremental Link without manifests\n"; |
|---|
| 4046 |
} |
|---|
| 4047 |
} |
|---|
| 4048 |
return cmake::VisualStudioLinkNonIncremental(expandedArgs, |
|---|
| 4049 |
type, hasManifest, verbose); |
|---|
| 4050 |
} |
|---|
| 4051 |
|
|---|
| 4052 |
int cmake::ParseVisualStudioLinkCommand(std::vector<std::string>& args, |
|---|
| 4053 |
std::vector<cmStdString>& command, |
|---|
| 4054 |
std::string& targetName) |
|---|
| 4055 |
{ |
|---|
| 4056 |
std::vector<std::string>::iterator i = args.begin(); |
|---|
| 4057 |
i++; // skip -E |
|---|
| 4058 |
i++; // skip vs_link_dll or vs_link_exe |
|---|
| 4059 |
command.push_back(*i); |
|---|
| 4060 |
i++; // move past link command |
|---|
| 4061 |
for(; i != args.end(); ++i) |
|---|
| 4062 |
{ |
|---|
| 4063 |
command.push_back(*i); |
|---|
| 4064 |
if(i->find("/Fe") == 0) |
|---|
| 4065 |
{ |
|---|
| 4066 |
targetName = i->substr(3); |
|---|
| 4067 |
} |
|---|
| 4068 |
if(i->find("/out:") == 0) |
|---|
| 4069 |
{ |
|---|
| 4070 |
targetName = i->substr(5); |
|---|
| 4071 |
} |
|---|
| 4072 |
} |
|---|
| 4073 |
if(targetName.size() == 0 || command.size() == 0) |
|---|
| 4074 |
{ |
|---|
| 4075 |
return -1; |
|---|
| 4076 |
} |
|---|
| 4077 |
return 0; |
|---|
| 4078 |
} |
|---|
| 4079 |
|
|---|
| 4080 |
bool cmake::RunCommand(const char* comment, |
|---|
| 4081 |
std::vector<cmStdString>& command, |
|---|
| 4082 |
bool verbose, |
|---|
| 4083 |
int* retCodeOut) |
|---|
| 4084 |
{ |
|---|
| 4085 |
if(verbose) |
|---|
| 4086 |
{ |
|---|
| 4087 |
std::cout << comment << ":\n"; |
|---|
| 4088 |
for(std::vector<cmStdString>::iterator i = command.begin(); |
|---|
| 4089 |
i != command.end(); ++i) |
|---|
| 4090 |
{ |
|---|
| 4091 |
std::cout << i->c_str() << " "; |
|---|
| 4092 |
} |
|---|
| 4093 |
std::cout << "\n"; |
|---|
| 4094 |
} |
|---|
| 4095 |
std::string output; |
|---|
| 4096 |
int retCode =0; |
|---|
| 4097 |
// use rc command to create .res file |
|---|
| 4098 |
cmSystemTools::RunSingleCommand(command, |
|---|
| 4099 |
&output, |
|---|
| 4100 |
&retCode, 0, false); |
|---|
| 4101 |
// always print the output of the command, unless |
|---|
| 4102 |
// it is the dumb rc command banner, but if the command |
|---|
| 4103 |
// returned an error code then print the output anyway as |
|---|
| 4104 |
// the banner may be mixed with some other important information. |
|---|
| 4105 |
if(output.find("Resource Compiler Version") == output.npos |
|---|
| 4106 |
|| retCode !=0) |
|---|
| 4107 |
{ |
|---|
| 4108 |
std::cout << output; |
|---|
| 4109 |
} |
|---|
| 4110 |
// if retCodeOut is requested then always return true |
|---|
| 4111 |
// and set the retCodeOut to retCode |
|---|
| 4112 |
if(retCodeOut) |
|---|
| 4113 |
{ |
|---|
| 4114 |
*retCodeOut = retCode; |
|---|
| 4115 |
return true; |
|---|
| 4116 |
} |
|---|
| 4117 |
if(retCode != 0) |
|---|
| 4118 |
{ |
|---|
| 4119 |
std::cout << comment << " failed. with " << retCode << "\n"; |
|---|
| 4120 |
} |
|---|
| 4121 |
return retCode == 0; |
|---|
| 4122 |
} |
|---|
| 4123 |
|
|---|
| 4124 |
int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args, |
|---|
| 4125 |
int type, bool verbose) |
|---|
| 4126 |
{ |
|---|
| 4127 |
// This follows the steps listed here: |
|---|
| 4128 |
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx |
|---|
| 4129 |
|
|---|
| 4130 |
// 1. Compiler compiles the application and generates the *.obj files. |
|---|
| 4131 |
// 2. An empty manifest file is generated if this is a clean build and if |
|---|
| 4132 |
// not the previous one is reused. |
|---|
| 4133 |
// 3. The resource compiler (rc.exe) compiles the *.manifest file to a |
|---|
| 4134 |
// *.res file. |
|---|
| 4135 |
// 4. Linker generates the binary (EXE or DLL) with the /incremental |
|---|
| 4136 |
// switch and embeds the dummy manifest file. The linker also generates |
|---|
| 4137 |
// the real manifest file based on the binaries that your binary depends |
|---|
| 4138 |
// on. |
|---|
| 4139 |
// 5. The manifest tool (mt.exe) is then used to generate the final |
|---|
| 4140 |
// manifest. |
|---|
| 4141 |
|
|---|
| 4142 |
// If the final manifest is changed, then 6 and 7 are run, if not |
|---|
| 4143 |
// they are skipped, and it is done. |
|---|
| 4144 |
|
|---|
| 4145 |
// 6. The resource compiler is invoked one more time. |
|---|
| 4146 |
// 7. Finally, the Linker does another incremental link, but since the |
|---|
| 4147 |
// only thing that has changed is the *.res file that contains the |
|---|
| 4148 |
// manifest it is a short link. |
|---|
| 4149 |
std::vector<cmStdString> linkCommand; |
|---|
| 4150 |
std::string targetName; |
|---|
| 4151 |
if(cmake::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1) |
|---|
| 4152 |
{ |
|---|
| 4153 |
return -1; |
|---|
| 4154 |
} |
|---|
| 4155 |
std::string manifestArg = "/MANIFESTFILE:"; |
|---|
| 4156 |
std::vector<cmStdString> rcCommand; |
|---|
| 4157 |
rcCommand.push_back(cmSystemTools::FindProgram("rc.exe")); |
|---|
| 4158 |
std::vector<cmStdString> mtCommand; |
|---|
| 4159 |
mtCommand.push_back(cmSystemTools::FindProgram("mt.exe")); |
|---|
| 4160 |
std::string tempManifest; |
|---|
| 4161 |
tempManifest = targetName; |
|---|
| 4162 |
tempManifest += ".intermediate.manifest"; |
|---|
| 4163 |
std::string resourceInputFile = targetName; |
|---|
| 4164 |
resourceInputFile += ".resource.txt"; |
|---|
| 4165 |
if(verbose) |
|---|
| 4166 |
{ |
|---|
| 4167 |
std::cout << "Create " << resourceInputFile.c_str() << "\n"; |
|---|
| 4168 |
} |
|---|
| 4169 |
// Create input file for rc command |
|---|
| 4170 |
std::ofstream fout(resourceInputFile.c_str()); |
|---|
| 4171 |
if(!fout) |
|---|
| 4172 |
{ |
|---|
| 4173 |
return -1; |
|---|
| 4174 |
} |
|---|
| 4175 |
std::string manifestFile = targetName; |
|---|
| 4176 |
manifestFile += ".embed.manifest"; |
|---|
| 4177 |
std::string fullPath= cmSystemTools::CollapseFullPath(manifestFile.c_str()); |
|---|
| 4178 |
fout << type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID " |
|---|
| 4179 |
"*/ 24 /* RT_MANIFEST */ " << "\"" << fullPath.c_str() << "\""; |
|---|
| 4180 |
fout.close(); |
|---|
| 4181 |
manifestArg += tempManifest; |
|---|
| 4182 |
// add the manifest arg to the linkCommand |
|---|
| 4183 |
linkCommand.push_back("/MANIFEST"); |
|---|
| 4184 |
linkCommand.push_back(manifestArg); |
|---|
| 4185 |
// if manifestFile is not yet created, create an |
|---|
| 4186 |
// empty one |
|---|
| 4187 |
if(!cmSystemTools::FileExists(manifestFile.c_str())) |
|---|
| 4188 |
{ |
|---|
| 4189 |
if(verbose) |
|---|
| 4190 |
{ |
|---|
| 4191 |
std::cout << "Create empty: " << manifestFile.c_str() << "\n"; |
|---|
| 4192 |
} |
|---|
| 4193 |
std::ofstream foutTmp(manifestFile.c_str()); |
|---|
| 4194 |
} |
|---|
| 4195 |
std::string resourceFile = manifestFile; |
|---|
| 4196 |
resourceFile += ".res"; |
|---|
| 4197 |
// add the resource file to the end of the link command |
|---|
| 4198 |
linkCommand.push_back(resourceFile); |
|---|
| 4199 |
std::string outputOpt = "/fo"; |
|---|
| 4200 |
outputOpt += resourceFile; |
|---|
| 4201 |
rcCommand.push_back(outputOpt); |
|---|
| 4202 |
rcCommand.push_back(resourceInputFile); |
|---|
| 4203 |
// Run rc command to create resource |
|---|
| 4204 |
if(!cmake::RunCommand("RC Pass 1", rcCommand, verbose)) |
|---|
| 4205 |
{ |
|---|
| 4206 |
return -1; |
|---|
| 4207 |
} |
|---|
| 4208 |
// Now run the link command to link and create manifest |
|---|
| 4209 |
if(!cmake::RunCommand("LINK Pass 1", linkCommand, verbose)) |
|---|
| 4210 |
{ |
|---|
| 4211 |
return -1; |
|---|
| 4212 |
} |
|---|
| 4213 |
// create mt command |
|---|
| 4214 |
std::string outArg("/out:"); |
|---|
| 4215 |
outArg+= manifestFile; |
|---|
| 4216 |
mtCommand.push_back("/nologo"); |
|---|
| 4217 |
mtCommand.push_back(outArg); |
|---|
| 4218 |
mtCommand.push_back("/notify_update"); |
|---|
| 4219 |
mtCommand.push_back("/manifest"); |
|---|
| 4220 |
mtCommand.push_back(tempManifest); |
|---|
| 4221 |
// now run mt.exe to create the final manifest file |
|---|
| 4222 |
int mtRet =0; |
|---|
| 4223 |
cmake::RunCommand("MT", mtCommand, verbose, &mtRet); |
|---|
| 4224 |
// if mt returns 0, then the manifest was not changed and |
|---|
| 4225 |
// we do not need to do another link step |
|---|
| 4226 |
if(mtRet == 0) |
|---|
| 4227 |
{ |
|---|
| 4228 |
return 0; |
|---|
| 4229 |
} |
|---|
| 4230 |
// check for magic mt return value if mt returns the magic number |
|---|
| 4231 |
// 1090650113 then it means that it updated the manifest file and we need |
|---|
| 4232 |
// to do the final link. If mt has any value other than 0 or 1090650113 |
|---|
| 4233 |
// then there was some problem with the command itself and there was an |
|---|
| 4234 |
// error so return the error code back out of cmake so make can report it. |
|---|
| 4235 |
if(mtRet != 1090650113) |
|---|
| 4236 |
{ |
|---|
| 4237 |
return mtRet; |
|---|
| 4238 |
} |
|---|
| 4239 |
// update the resource file with the new manifest from the mt command. |
|---|
| 4240 |
if(!cmake::RunCommand("RC Pass 2", rcCommand, verbose)) |
|---|
| 4241 |
{ |
|---|
| 4242 |
return -1; |
|---|
| 4243 |
} |
|---|
| 4244 |
// Run the final incremental link that will put the new manifest resource |
|---|
| 4245 |
// into the file incrementally. |
|---|
| 4246 |
if(!cmake::RunCommand("FINAL LINK", linkCommand, verbose)) |
|---|
| 4247 |
{ |
|---|
| 4248 |
return -1; |
|---|
| 4249 |
} |
|---|
| 4250 |
return 0; |
|---|
| 4251 |
} |
|---|
| 4252 |
|
|---|
| 4253 |
int cmake::VisualStudioLinkNonIncremental(std::vector<std::string>& args, |
|---|
| 4254 |
int type, |
|---|
| 4255 |
bool hasManifest, |
|---|
| 4256 |
bool verbose) |
|---|
| 4257 |
{ |
|---|
| 4258 |
std::vector<cmStdString> linkCommand; |
|---|
| 4259 |
std::string targetName; |
|---|
| 4260 |
if(cmake::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1) |
|---|
| 4261 |
{ |
|---|
| 4262 |
return -1; |
|---|
| 4263 |
} |
|---|
| 4264 |
// Run the link command as given |
|---|
| 4265 |
linkCommand.push_back("/MANIFEST"); |
|---|
| 4266 |
if(!cmake::RunCommand("LINK", linkCommand, verbose)) |
|---|
| 4267 |
{ |
|---|
| 4268 |
return -1; |
|---|
| 4269 |
} |
|---|
| 4270 |
if(!hasManifest) |
|---|
| 4271 |
{ |
|---|
| 4272 |
return 0; |
|---|
| 4273 |
} |
|---|
| 4274 |
std::vector<cmStdString> mtCommand; |
|---|
| 4275 |
mtCommand.push_back(cmSystemTools::FindProgram("mt.exe")); |
|---|
| 4276 |
mtCommand.push_back("/nologo"); |
|---|
| 4277 |
mtCommand.push_back("/manifest"); |
|---|
| 4278 |
std::string manifestFile = targetName; |
|---|
| 4279 |
manifestFile += ".manifest"; |
|---|
| 4280 |
mtCommand.push_back(manifestFile); |
|---|
| 4281 |
std::string outresource = "/outputresource:"; |
|---|
| 4282 |
outresource += targetName; |
|---|
| 4283 |
outresource += ";#"; |
|---|
| 4284 |
if(type == 1) |
|---|
| 4285 |
{ |
|---|
| 4286 |
outresource += "1"; |
|---|
| 4287 |
} |
|---|
| 4288 |
else if(type == 2) |
|---|
| 4289 |
{ |
|---|
| 4290 |
outresource += "2"; |
|---|
| 4291 |
} |
|---|
| 4292 |
mtCommand.push_back(outresource); |
|---|
| 4293 |
// Now use the mt tool to embed the manifest into the exe or dll |
|---|
| 4294 |
if(!cmake::RunCommand("MT", mtCommand, verbose)) |
|---|
| 4295 |
{ |
|---|
| 4296 |
return -1; |
|---|
| 4297 |
} |
|---|
| 4298 |
return 0; |
|---|
| 4299 |
} |
|---|
| 4300 |
|
|---|
| 4301 |
//---------------------------------------------------------------------------- |
|---|
| 4302 |
void cmake::IssueMessage(cmake::MessageType t, std::string const& text, |
|---|
| 4303 |
cmListFileBacktrace const& backtrace) |
|---|
| 4304 |
{ |
|---|
| 4305 |
cmOStringStream msg; |
|---|
| 4306 |
bool isError = false; |
|---|
| 4307 |
// Construct the message header. |
|---|
| 4308 |
if(t == cmake::FATAL_ERROR) |
|---|
| 4309 |
{ |
|---|
| 4310 |
isError = true; |
|---|
| 4311 |
msg << "CMake Error"; |
|---|
| 4312 |
} |
|---|
| 4313 |
else if(t == cmake::INTERNAL_ERROR) |
|---|
| 4314 |
{ |
|---|
| 4315 |
isError = true; |
|---|
| 4316 |
msg << "CMake Internal Error (please report a bug)"; |
|---|
| 4317 |
} |
|---|
| 4318 |
else |
|---|
| 4319 |
{ |
|---|
| 4320 |
msg << "CMake Warning"; |
|---|
| 4321 |
if(t == cmake::AUTHOR_WARNING) |
|---|
| 4322 |
{ |
|---|
| 4323 |
// Allow suppression of these warnings. |
|---|
| 4324 |
cmCacheManager::CacheIterator it = this->CacheManager |
|---|
| 4325 |
->GetCacheIterator("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"); |
|---|
| 4326 |
if(!it.IsAtEnd() && it.GetValueAsBool()) |
|---|
| 4327 |
{ |
|---|
| 4328 |
return; |
|---|
| 4329 |
} |
|---|
| 4330 |
msg << " (dev)"; |
|---|
| 4331 |
} |
|---|
| 4332 |
} |
|---|
| 4333 |
|
|---|
| 4334 |
// Add the immediate context. |
|---|
| 4335 |
cmListFileBacktrace::const_iterator i = backtrace.begin(); |
|---|
| 4336 |
if(i != backtrace.end()) |
|---|
| 4337 |
{ |
|---|
| 4338 |
cmListFileContext const& lfc = *i; |
|---|
| 4339 |
msg << (lfc.Line? " at ": " in ") << lfc; |
|---|
| 4340 |
++i; |
|---|
| 4341 |
} |
|---|
| 4342 |
|
|---|
| 4343 |
// Add the message text. |
|---|
| 4344 |
{ |
|---|
| 4345 |
msg << ":\n"; |
|---|
| 4346 |
cmDocumentationFormatterText formatter; |
|---|
| 4347 |
formatter.SetIndent(" "); |
|---|
| 4348 |
formatter.PrintFormatted(msg, text.c_str()); |
|---|
| 4349 |
} |
|---|
| 4350 |
|
|---|
| 4351 |
// Add the rest of the context. |
|---|
| 4352 |
if(i != backtrace.end()) |
|---|
| 4353 |
{ |
|---|
| 4354 |
msg << "Call Stack (most recent call first):\n"; |
|---|
| 4355 |
while(i != backtrace.end()) |
|---|
| 4356 |
{ |
|---|
| 4357 |
cmListFileContext const& lfc = *i; |
|---|
| 4358 |
msg << " " << lfc << "\n"; |
|---|
| 4359 |
++i; |
|---|
| 4360 |
} |
|---|
| 4361 |
} |
|---|
| 4362 |
|
|---|
| 4363 |
// Add a note about warning suppression. |
|---|
| 4364 |
if(t == cmake::AUTHOR_WARNING) |
|---|
| 4365 |
{ |
|---|
| 4366 |
msg << |
|---|
| 4367 |
"This warning is for project developers. Use -Wno-dev to suppress it."; |
|---|
| 4368 |
} |
|---|
| 4369 |
|
|---|
| 4370 |
// Add a terminating blank line. |
|---|
| 4371 |
msg << "\n"; |
|---|
| 4372 |
|
|---|
| 4373 |
// Output the message. |
|---|
| 4374 |
if(isError) |
|---|
| 4375 |
{ |
|---|
| 4376 |
cmSystemTools::SetErrorOccured(); |
|---|
| 4377 |
cmSystemTools::Message(msg.str().c_str(), "Error"); |
|---|
| 4378 |
} |
|---|
| 4379 |
else |
|---|
| 4380 |
{ |
|---|
| 4381 |
cmSystemTools::Message(msg.str().c_str(), "Warning"); |
|---|
| 4382 |
} |
|---|
| 4383 |
} |
|---|
| 4384 |
|
|---|
| 4385 |
//---------------------------------------------------------------------------- |
|---|
| 4386 |
std::vector<std::string> const& cmake::GetDebugConfigs() |
|---|
| 4387 |
{ |
|---|
| 4388 |
// Compute on-demand. |
|---|
| 4389 |
if(this->DebugConfigs.empty()) |
|---|
| 4390 |
{ |
|---|
| 4391 |
if(const char* config_list = this->GetProperty("DEBUG_CONFIGURATIONS")) |
|---|
| 4392 |
{ |
|---|
| 4393 |
// Expand the specified list and convert to upper-case. |
|---|
| 4394 |
cmSystemTools::ExpandListArgument(config_list, this->DebugConfigs); |
|---|
| 4395 |
for(std::vector<std::string>::iterator i = this->DebugConfigs.begin(); |
|---|
| 4396 |
i != this->DebugConfigs.end(); ++i) |
|---|
| 4397 |
{ |
|---|
| 4398 |
*i = cmSystemTools::UpperCase(*i); |
|---|
| 4399 |
} |
|---|
| 4400 |
} |
|---|
| 4401 |
// If no configurations were specified, use a default list. |
|---|
| 4402 |
if(this->DebugConfigs.empty()) |
|---|
| 4403 |
{ |
|---|
| 4404 |
this->DebugConfigs.push_back("DEBUG"); |
|---|
| 4405 |
} |
|---|
| 4406 |
} |
|---|
| 4407 |
return this->DebugConfigs; |
|---|
| 4408 |
} |
|---|
| 4409 |
|
|---|
| 4410 |
|
|---|
| 4411 |
int cmake::Build(const std::string& dir, |
|---|
| 4412 |
const std::string& target, |
|---|
| 4413 |
const std::string& config, |
|---|
| 4414 |
const std::vector<std::string>& nativeOptions, |
|---|
| 4415 |
bool clean) |
|---|
| 4416 |
{ |
|---|
| 4417 |
if(!cmSystemTools::FileIsDirectory(dir.c_str())) |
|---|
| 4418 |
{ |
|---|
| 4419 |
std::cerr << "Error: " << dir << " is not a directory\n"; |
|---|
| 4420 |
return 1; |
|---|
| 4421 |
} |
|---|
| 4422 |
std::string cachePath = dir; |
|---|
| 4423 |
cmSystemTools::ConvertToUnixSlashes(cachePath); |
|---|
| 4424 |
cmCacheManager* cachem = this->GetCacheManager(); |
|---|
| 4425 |
cmCacheManager::CacheIterator it = cachem->NewIterator(); |
|---|
| 4426 |
if(!cachem->LoadCache(cachePath.c_str())) |
|---|
| 4427 |
{ |
|---|
| 4428 |
std::cerr << "Error: could not load cache\n"; |
|---|
| 4429 |
return 1; |
|---|
| 4430 |
} |
|---|
| 4431 |
if(!it.Find("CMAKE_GENERATOR")) |
|---|
| 4432 |
{ |
|---|
| 4433 |
std::cerr << "Error: could find generator in Cache\n"; |
|---|
| 4434 |
return 1; |
|---|
| 4435 |
} |
|---|
| 4436 |
std::auto_ptr<cmGlobalGenerator> gen( |
|---|
| 4437 |
this->CreateGlobalGenerator(it.GetValue())); |
|---|
| 4438 |
std::string output; |
|---|
| 4439 |
std::string projName; |
|---|
| 4440 |
std::string makeProgram; |
|---|
| 4441 |
if(!it.Find("CMAKE_PROJECT_NAME")) |
|---|
| 4442 |
{ |
|---|
| 4443 |
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; |
|---|
| 4444 |
return 1; |
|---|
| 4445 |
} |
|---|
| 4446 |
projName = it.GetValue(); |
|---|
| 4447 |
if(!it.Find("CMAKE_MAKE_PROGRAM")) |
|---|
| 4448 |
{ |
|---|
| 4449 |
std::cerr << "Error: could not find CMAKE_MAKE_PROGRAM in Cache\n"; |
|---|
| 4450 |
return 1; |
|---|
| 4451 |
} |
|---|
| 4452 |
makeProgram = it.GetValue(); |
|---|
| 4453 |
return gen->Build(0, dir.c_str(), |
|---|
| 4454 |
projName.c_str(), target.c_str(), |
|---|
| 4455 |
&output, |
|---|
| 4456 |
makeProgram.c_str(), |
|---|
| 4457 |
config.c_str(), clean, false, 0, true, |
|---|
| 4458 |
0, nativeOptions); |
|---|
| 4459 |
} |
|---|