cmake.cxx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Insight Consortium. All rights reserved.
  8. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmake.h"
  14. #include "time.h"
  15. #include "cmCacheManager.h"
  16. #include "cmMakefile.h"
  17. #include "cmLocalGenerator.h"
  18. #include "cmCommands.h"
  19. #include "cmCommand.h"
  20. // include the generator
  21. #if defined(_WIN32) && !defined(__CYGWIN__)
  22. #include "cmGlobalVisualStudio6Generator.h"
  23. #include "cmGlobalVisualStudio7Generator.h"
  24. #include "cmGlobalBorlandMakefileGenerator.h"
  25. #include "cmGlobalNMakeMakefileGenerator.h"
  26. #else
  27. #include "cmGlobalUnixMakefileGenerator.h"
  28. #endif
  29. #include <stdio.h>
  30. cmake::cmake()
  31. {
  32. m_Verbose = false;
  33. m_CacheManager = new cmCacheManager;
  34. m_GlobalGenerator = 0;
  35. this->AddDefaultCommands();
  36. }
  37. cmake::~cmake()
  38. {
  39. delete m_CacheManager;
  40. if (m_GlobalGenerator)
  41. {
  42. delete m_GlobalGenerator;
  43. m_GlobalGenerator = 0;
  44. }
  45. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  46. j != m_Commands.end(); ++j)
  47. {
  48. delete (*j).second;
  49. }
  50. }
  51. bool cmake::CommandExists(const char* name) const
  52. {
  53. return (m_Commands.find(name) != m_Commands.end());
  54. }
  55. cmCommand *cmake::GetCommand(const char *name)
  56. {
  57. cmCommand* rm = 0;
  58. RegisteredCommandsMap::iterator pos = m_Commands.find(name);
  59. if (pos != m_Commands.end())
  60. {
  61. rm = (*pos).second;
  62. }
  63. return rm;
  64. }
  65. void cmake::AddCommand(cmCommand* wg)
  66. {
  67. std::string name = wg->GetName();
  68. m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
  69. }
  70. void cmake::Usage(const char* program)
  71. {
  72. cmStringStream errorStream;
  73. errorStream << "cmake version " << cmMakefile::GetMajorVersion()
  74. << "." << cmMakefile::GetMinorVersion() << "\n";
  75. errorStream << "Usage: " << program << " [srcdir] [options]\n"
  76. << "Where cmake is run from the directory where you want the object files written. If srcdir is not specified, the current directory is used for both source and object files.\n";
  77. errorStream << "Options are:\n";
  78. errorStream << "\n-i (puts cmake in wizard mode, not available for ccmake)\n";
  79. errorStream << "\n-DVAR:TYPE=VALUE (create a cache file entry)\n";
  80. errorStream << "\n-Cpath_to_initial_cache (a cmake list file that is used to pre-load the cache with values.)\n";
  81. errorStream << "\n[-GgeneratorName] (where generator name can be one of these: ";
  82. std::vector<std::string> names;
  83. this->GetRegisteredGenerators(names);
  84. for(std::vector<std::string>::iterator i =names.begin();
  85. i != names.end(); ++i)
  86. {
  87. errorStream << "\"" << i->c_str() << "\" ";
  88. }
  89. errorStream << ")\n";
  90. cmSystemTools::Error(errorStream.str().c_str());
  91. }
  92. // Parse the args
  93. void cmake::SetCacheArgs(const std::vector<std::string>& args)
  94. {
  95. for(unsigned int i=1; i < args.size(); ++i)
  96. {
  97. std::string arg = args[i];
  98. if(arg.find("-D",0) == 0)
  99. {
  100. std::string entry = arg.substr(2);
  101. std::string var, value;
  102. cmCacheManager::CacheEntryType type;
  103. if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type))
  104. {
  105. this->m_CacheManager->AddCacheEntry(var.c_str(), value.c_str(),
  106. "No help, variable specified on the command line.",
  107. type);
  108. }
  109. else
  110. {
  111. std::cerr << "Parse error in command line argument: " << arg << "\n"
  112. << "Should be: VAR:type=value\n";
  113. }
  114. }
  115. else if(arg.find("-C",0) == 0)
  116. {
  117. std::string path = arg.substr(2);
  118. std::cerr << "loading initial cache file " << path.c_str() << "\n";
  119. this->ReadListFile(path.c_str());
  120. }
  121. }
  122. }
  123. void cmake::ReadListFile(const char *path)
  124. {
  125. // if a generator was not yet created, temporarily create one
  126. cmGlobalGenerator *gg = this->GetGlobalGenerator();
  127. bool created = false;
  128. // if a generator was not specified use a generic one
  129. if (!gg)
  130. {
  131. gg = new cmGlobalGenerator;
  132. gg->SetCMakeInstance(this);
  133. created = true;
  134. }
  135. // read in the list file to fill the cache
  136. if(path)
  137. {
  138. cmLocalGenerator *lg = gg->CreateLocalGenerator();
  139. lg->SetGlobalGenerator(gg);
  140. if (!lg->GetMakefile()->ReadListFile(path))
  141. {
  142. std::cerr << "Error in reading cmake initial cache file:"
  143. << path << "\n";
  144. }
  145. }
  146. // free generic one if generated
  147. if (created)
  148. {
  149. delete gg;
  150. }
  151. }
  152. // Parse the args
  153. void cmake::SetArgs(const std::vector<std::string>& args)
  154. {
  155. m_Local = false;
  156. bool directoriesSet = false;
  157. // watch for cmake and cmake srcdir invocations
  158. if (args.size() <= 2)
  159. {
  160. directoriesSet = true;
  161. this->SetHomeOutputDirectory
  162. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  163. this->SetStartOutputDirectory
  164. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  165. if (args.size() == 2)
  166. {
  167. this->SetHomeDirectory
  168. (cmSystemTools::CollapseFullPath(args[1].c_str()).c_str());
  169. this->SetStartDirectory
  170. (cmSystemTools::CollapseFullPath(args[1].c_str()).c_str());
  171. }
  172. else
  173. {
  174. this->SetHomeDirectory
  175. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  176. this->SetStartDirectory
  177. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  178. }
  179. }
  180. for(unsigned int i=1; i < args.size(); ++i)
  181. {
  182. std::string arg = args[i];
  183. if(arg.find("-H",0) == 0)
  184. {
  185. directoriesSet = true;
  186. std::string path = arg.substr(2);
  187. this->SetHomeDirectory(path.c_str());
  188. }
  189. else if(arg.find("-S",0) == 0)
  190. {
  191. directoriesSet = true;
  192. m_Local = true;
  193. std::string path = arg.substr(2);
  194. this->SetStartDirectory(path.c_str());
  195. }
  196. else if(arg.find("-O",0) == 0)
  197. {
  198. directoriesSet = true;
  199. std::string path = arg.substr(2);
  200. this->SetStartOutputDirectory(path.c_str());
  201. }
  202. else if(arg.find("-B",0) == 0)
  203. {
  204. directoriesSet = true;
  205. std::string path = arg.substr(2);
  206. this->SetHomeOutputDirectory(path.c_str());
  207. }
  208. else if(arg.find("-V",0) == 0)
  209. {
  210. m_Verbose = true;
  211. }
  212. else if(arg.find("-D",0) == 0)
  213. {
  214. // skip for now
  215. }
  216. else if(arg.find("-C",0) == 0)
  217. {
  218. // skip for now
  219. }
  220. else if(arg.find("-G",0) == 0)
  221. {
  222. std::string value = arg.substr(2);
  223. cmGlobalGenerator* gen =
  224. this->CreateGlobalGenerator(value.c_str());
  225. if(!gen)
  226. {
  227. cmSystemTools::Error("Could not create named generator ",
  228. value.c_str());
  229. }
  230. else
  231. {
  232. this->SetGlobalGenerator(gen);
  233. }
  234. }
  235. // no option assume it is the path to the source
  236. else
  237. {
  238. directoriesSet = true;
  239. this->SetHomeOutputDirectory
  240. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  241. this->SetStartOutputDirectory
  242. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  243. this->SetHomeDirectory
  244. (cmSystemTools::CollapseFullPath(arg.c_str()).c_str());
  245. this->SetStartDirectory
  246. (cmSystemTools::CollapseFullPath(arg.c_str()).c_str());
  247. }
  248. }
  249. if(!directoriesSet)
  250. {
  251. this->SetHomeOutputDirectory
  252. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  253. this->SetStartOutputDirectory
  254. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  255. this->SetHomeDirectory
  256. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  257. this->SetStartDirectory
  258. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  259. }
  260. if (!m_Local)
  261. {
  262. this->SetStartDirectory(this->GetHomeDirectory());
  263. this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
  264. }
  265. }
  266. // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache
  267. int cmake::AddCMakePaths(const char *arg0)
  268. {
  269. // Find our own executable.
  270. std::vector<cmStdString> failures;
  271. std::string cMakeSelf = arg0;
  272. cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
  273. failures.push_back(cMakeSelf);
  274. cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str());
  275. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  276. {
  277. #ifdef CMAKE_BUILD_DIR
  278. std::string intdir = ".";
  279. #ifdef CMAKE_INTDIR
  280. intdir = CMAKE_INTDIR;
  281. #endif
  282. cMakeSelf = CMAKE_BUILD_DIR;
  283. cMakeSelf += "/Source/";
  284. cMakeSelf += intdir;
  285. cMakeSelf += "/cmake";
  286. cMakeSelf += cmSystemTools::GetExecutableExtension();
  287. #endif
  288. }
  289. #ifdef CMAKE_PREFIX
  290. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  291. {
  292. failures.push_back(cMakeSelf);
  293. cMakeSelf = CMAKE_PREFIX "/bin/cmake";
  294. }
  295. #endif
  296. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  297. {
  298. failures.push_back(cMakeSelf);
  299. cmStringStream msg;
  300. msg << "CMAKE can not find the command line program cmake.\n";
  301. msg << " argv[0] = \"" << arg0 << "\"\n";
  302. msg << " Attempted paths:\n";
  303. std::vector<cmStdString>::iterator i;
  304. for(i=failures.begin(); i != failures.end(); ++i)
  305. {
  306. msg << " \"" << i->c_str() << "\"\n";
  307. }
  308. cmSystemTools::Error(msg.str().c_str());
  309. return 0;
  310. }
  311. // Save the value in the cache
  312. this->m_CacheManager->AddCacheEntry
  313. ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.",
  314. cmCacheManager::INTERNAL);
  315. // Find and save the command to edit the cache
  316. std::string editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  317. "/ccmake" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  318. if( !cmSystemTools::FileExists(editCacheCommand.c_str()))
  319. {
  320. editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  321. "/CMakeSetup" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  322. }
  323. if(cmSystemTools::FileExists(editCacheCommand.c_str()))
  324. {
  325. this->m_CacheManager->AddCacheEntry
  326. ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
  327. "Path to cache edit program executable.", cmCacheManager::INTERNAL);
  328. }
  329. // do CMAKE_ROOT, look for the environment variable first
  330. std::string cMakeRoot;
  331. std::string modules;
  332. if (getenv("CMAKE_ROOT"))
  333. {
  334. cMakeRoot = getenv("CMAKE_ROOT");
  335. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  336. }
  337. if(!cmSystemTools::FileExists(modules.c_str()))
  338. {
  339. // next try exe/..
  340. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  341. std::string::size_type slashPos = cMakeRoot.rfind("/");
  342. if(slashPos != std::string::npos)
  343. {
  344. cMakeRoot = cMakeRoot.substr(0, slashPos);
  345. }
  346. // is there no Modules direcory there?
  347. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  348. }
  349. if (!cmSystemTools::FileExists(modules.c_str()))
  350. {
  351. // try exe/../share/cmake
  352. cMakeRoot += "/share/CMake";
  353. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  354. }
  355. #ifdef CMAKE_ROOT_DIR
  356. if (!cmSystemTools::FileExists(modules.c_str()))
  357. {
  358. // try compiled in root directory
  359. cMakeRoot = CMAKE_ROOT_DIR;
  360. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  361. }
  362. #endif
  363. #ifdef CMAKE_PREFIX
  364. if (!cmSystemTools::FileExists(modules.c_str()))
  365. {
  366. // try compiled in install prefix
  367. cMakeRoot = CMAKE_PREFIX "/share/CMake";
  368. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  369. }
  370. #endif
  371. if (!cmSystemTools::FileExists(modules.c_str()))
  372. {
  373. // try
  374. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  375. cMakeRoot += "/share/CMake";
  376. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  377. }
  378. if(!cmSystemTools::FileExists(modules.c_str()))
  379. {
  380. // next try exe
  381. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  382. // is there no Modules direcory there?
  383. modules = cMakeRoot + "/Modules/FindVTK.cmake";
  384. }
  385. if (!cmSystemTools::FileExists(modules.c_str()))
  386. {
  387. // couldn't find modules
  388. cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n",
  389. "Modules directory not in directory:\n",
  390. modules.c_str());
  391. return 0;
  392. }
  393. this->m_CacheManager->AddCacheEntry
  394. ("CMAKE_ROOT", cMakeRoot.c_str(),
  395. "Path to CMake installation.", cmCacheManager::INTERNAL);
  396. return 1;
  397. }
  398. void CMakeCommandUsage(const char* program)
  399. {
  400. cmStringStream errorStream;
  401. errorStream
  402. << "cmake version " << cmMakefile::GetMajorVersion()
  403. << "." << cmMakefile::GetMinorVersion() << "\n";
  404. errorStream
  405. << "Usage: " << program << " -E [command] [arguments ...]\n"
  406. << "Available commands: \n"
  407. << " chdir dir cmd [args]... - run command in a given directory\n"
  408. << " copy file destination - copy file to destination (either file or directory)\n"
  409. << " remove file1 file2 ... - remove the file(s)\n"
  410. << " time command [args] ... - run command and return elapsed time\n";
  411. #if defined(_WIN32) && !defined(__CYGWIN__)
  412. errorStream
  413. << " write_regv key value - write registry value\n"
  414. << " delete_regv key - delete registry value\n";
  415. #endif
  416. cmSystemTools::Error(errorStream.str().c_str());
  417. }
  418. int cmake::CMakeCommand(std::vector<std::string>& args)
  419. {
  420. if (args.size() > 1)
  421. {
  422. // Copy file
  423. if (args[1] == "copy" && args.size() == 4)
  424. {
  425. cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str());
  426. return cmSystemTools::GetErrorOccuredFlag();
  427. }
  428. // Remove file
  429. else if (args[1] == "remove" && args.size() > 2)
  430. {
  431. for (std::string::size_type cc = 2; cc < args.size(); cc ++)
  432. {
  433. if(args[cc] != "-f")
  434. {
  435. if(args[cc] == "\\-f")
  436. {
  437. args[cc] = "-f";
  438. }
  439. cmSystemTools::RemoveFile(args[cc].c_str());
  440. }
  441. }
  442. return 0;
  443. }
  444. // Clock command
  445. else if (args[1] == "time" && args.size() > 2)
  446. {
  447. std::string command = args[2];
  448. std::string output;
  449. for (std::string::size_type cc = 3; cc < args.size(); cc ++)
  450. {
  451. command += " ";
  452. command += args[cc];
  453. }
  454. clock_t clock_start, clock_finish;
  455. time_t time_start, time_finish;
  456. time(&time_start);
  457. clock_start = clock();
  458. cmSystemTools::RunCommand(command.c_str(), output, 0, true);
  459. clock_finish = clock();
  460. time(&time_finish);
  461. std::cout << output.c_str();
  462. double clocks_per_sec = (double)CLOCKS_PER_SEC;
  463. std::cout << "Elapsed time: "
  464. << (long)(time_finish - time_start) << " s. (time)"
  465. << ", "
  466. << (double)(clock_finish - clock_start) / clocks_per_sec
  467. << " s. (clock)"
  468. << "\n";
  469. return 0;
  470. }
  471. // Clock command
  472. else if (args[1] == "chdir" && args.size() > 2)
  473. {
  474. std::string directory = args[2];
  475. std::string command = args[3];
  476. std::string output;
  477. for (std::string::size_type cc = 4; cc < args.size(); cc ++)
  478. {
  479. command += " ";
  480. command += args[cc];
  481. }
  482. int retval = 0;
  483. if ( cmSystemTools::RunCommand(command.c_str(), output, retval,
  484. directory.c_str(), true) )
  485. {
  486. std::cout << output.c_str();
  487. return retval;
  488. }
  489. return 1;
  490. }
  491. #if defined(_WIN32) && !defined(__CYGWIN__)
  492. // Write registry value
  493. else if (args[1] == "write_regv" && args.size() > 3)
  494. {
  495. return cmSystemTools::WriteRegistryValue(args[2].c_str(),
  496. args[3].c_str()) ? 0 : 1;
  497. }
  498. // Delete registry value
  499. else if (args[1] == "delete_regv" && args.size() > 2)
  500. {
  501. return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
  502. }
  503. #endif
  504. }
  505. ::CMakeCommandUsage(args[0].c_str());
  506. return 1;
  507. }
  508. void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
  509. {
  510. #if defined(_WIN32) && !defined(__CYGWIN__)
  511. names.push_back(cmGlobalVisualStudio6Generator::GetActualName());
  512. names.push_back(cmGlobalVisualStudio7Generator::GetActualName());
  513. names.push_back(cmGlobalBorlandMakefileGenerator::GetActualName());
  514. names.push_back(cmGlobalNMakeMakefileGenerator::GetActualName());
  515. #else
  516. names.push_back(cmGlobalUnixMakefileGenerator::GetActualName());
  517. #endif
  518. }
  519. cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
  520. {
  521. cmGlobalGenerator *ret = 0;
  522. #if defined(_WIN32) && !defined(__CYGWIN__)
  523. if (!strcmp(name,cmGlobalNMakeMakefileGenerator::GetActualName()))
  524. {
  525. ret = new cmGlobalNMakeMakefileGenerator;
  526. ret->SetCMakeInstance(this);
  527. }
  528. if (!strcmp(name,cmGlobalVisualStudio6Generator::GetActualName()))
  529. {
  530. ret = new cmGlobalVisualStudio6Generator;
  531. ret->SetCMakeInstance(this);
  532. }
  533. if (!strcmp(name,cmGlobalVisualStudio7Generator::GetActualName()))
  534. {
  535. ret = new cmGlobalVisualStudio7Generator;
  536. ret->SetCMakeInstance(this);
  537. }
  538. if (!strcmp(name,cmGlobalBorlandMakefileGenerator::GetActualName()))
  539. {
  540. ret = new cmGlobalBorlandMakefileGenerator;
  541. ret->SetCMakeInstance(this);
  542. }
  543. #else
  544. if (!strcmp(name,cmGlobalUnixMakefileGenerator::GetActualName()))
  545. {
  546. ret = new cmGlobalUnixMakefileGenerator;
  547. ret->SetCMakeInstance(this);
  548. }
  549. #endif
  550. return ret;
  551. }
  552. void cmake::SetHomeDirectory(const char* dir)
  553. {
  554. m_cmHomeDirectory = dir;
  555. cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory);
  556. }
  557. void cmake::SetHomeOutputDirectory(const char* lib)
  558. {
  559. m_HomeOutputDirectory = lib;
  560. cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory);
  561. }
  562. void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
  563. {
  564. // delete the old generator
  565. if (m_GlobalGenerator)
  566. {
  567. delete m_GlobalGenerator;
  568. }
  569. // set the new
  570. m_GlobalGenerator = gg;
  571. // set the cmake instance just to be sure
  572. gg->SetCMakeInstance(this);
  573. }
  574. int cmake::Configure(const char *arg0, const std::vector<std::string>* args)
  575. {
  576. // Read in the cache
  577. m_CacheManager->LoadCache(this->GetHomeOutputDirectory());
  578. if(m_CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
  579. {
  580. std::string cacheStart =
  581. m_CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
  582. cacheStart += "/CMakeLists.txt";
  583. std::string currentStart = this->GetHomeDirectory();
  584. currentStart += "/CMakeLists.txt";
  585. if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
  586. {
  587. std::string message = "Error: source : ";
  588. message += currentStart;
  589. message += "\nDoes not match source used to generate cache: ";
  590. message += cacheStart;
  591. message += "\nRe-run cmake with a different source directory.";
  592. cmSystemTools::Error(message.c_str());
  593. return -2;
  594. }
  595. }
  596. else
  597. {
  598. m_CacheManager->AddCacheEntry("CMAKE_HOME_DIRECTORY",
  599. this->GetHomeDirectory(),
  600. "Start directory with the top level CMakeLists.txt file for this project",
  601. cmCacheManager::INTERNAL);
  602. }
  603. // extract command line arguments that might add cache entries
  604. if (args)
  605. {
  606. this->SetCacheArgs(*args);
  607. }
  608. // setup CMAKE_ROOT and CMAKE_COMMAND
  609. if(!this->AddCMakePaths(arg0))
  610. {
  611. return -3;
  612. }
  613. // no generator specified on the command line
  614. if(!m_GlobalGenerator)
  615. {
  616. const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
  617. if(genName)
  618. {
  619. m_GlobalGenerator = this->CreateGlobalGenerator(genName);
  620. }
  621. else
  622. {
  623. #if defined(__BORLANDC__) && defined(_WIN32)
  624. this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
  625. #elif defined(_WIN32) && !defined(__CYGWIN__)
  626. this->SetGlobalGenerator(new cmGlobalVisualStudio6Generator);
  627. #else
  628. this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator);
  629. #endif
  630. }
  631. if(!m_GlobalGenerator)
  632. {
  633. cmSystemTools::Error("Could not create generator");
  634. return -1;
  635. }
  636. }
  637. const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
  638. if(genName)
  639. {
  640. if(strcmp(m_GlobalGenerator->GetName(), genName) != 0)
  641. {
  642. std::string message = "Error: generator : ";
  643. message += m_GlobalGenerator->GetName();
  644. message += "\nDoes not match the generator used previously: ";
  645. message += genName;
  646. message +=
  647. "\nEither remove the CMakeCache.txt file or choose a different"
  648. " binary directory.";
  649. cmSystemTools::Error(message.c_str());
  650. return -2;
  651. }
  652. }
  653. if(!m_CacheManager->GetCacheValue("CMAKE_GENERATOR"))
  654. {
  655. m_CacheManager->AddCacheEntry("CMAKE_GENERATOR", m_GlobalGenerator->GetName(),
  656. "Name of generator.",
  657. cmCacheManager::INTERNAL);
  658. }
  659. // reset any system configuration information
  660. m_GlobalGenerator->ClearEnabledLanguages();
  661. // actually do the configure
  662. m_GlobalGenerator->Configure();
  663. // Before saving the cache
  664. // if the project did not define one of the entries below, add them now
  665. // so users can edit the values in the cache:
  666. // LIBRARY_OUTPUT_PATH
  667. // EXECUTABLE_OUTPUT_PATH
  668. if(!m_CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH"))
  669. {
  670. m_CacheManager->AddCacheEntry("LIBRARY_OUTPUT_PATH", "",
  671. "Single output directory for building all libraries.",
  672. cmCacheManager::PATH);
  673. }
  674. if(!m_CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
  675. {
  676. m_CacheManager->AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "",
  677. "Single output directory for building all executables.",
  678. cmCacheManager::PATH);
  679. }
  680. this->m_CacheManager->SaveCache(this->GetHomeOutputDirectory());
  681. if(cmSystemTools::GetErrorOccuredFlag())
  682. {
  683. return -1;
  684. }
  685. return 0;
  686. }
  687. // handle a command line invocation
  688. int cmake::Run(const std::vector<std::string>& args)
  689. {
  690. // a quick check for args
  691. if(args.size() == 1 && !cmSystemTools::FileExists("CMakeLists.txt"))
  692. {
  693. this->Usage(args[0].c_str());
  694. return -1;
  695. }
  696. // look for obvious request for help
  697. for(unsigned int i=1; i < args.size(); ++i)
  698. {
  699. std::string arg = args[i];
  700. if(arg.find("-help",0) != std::string::npos ||
  701. arg.find("--help",0) != std::string::npos ||
  702. arg.find("/?",0) != std::string::npos ||
  703. arg.find("-usage",0) != std::string::npos)
  704. {
  705. this->Usage(args[0].c_str());
  706. return -1;
  707. }
  708. }
  709. // Process the arguments
  710. this->SetArgs(args);
  711. // if we are local do the local thing, otherwise do global
  712. if (m_Local)
  713. {
  714. return this->LocalGenerate();
  715. }
  716. // otherwise global
  717. int ret = this->Configure(args[0].c_str(),&args);
  718. if (ret)
  719. {
  720. return ret;
  721. }
  722. return this->Generate();
  723. }
  724. int cmake::Generate()
  725. {
  726. m_GlobalGenerator->Generate();
  727. if(cmSystemTools::GetErrorOccuredFlag())
  728. {
  729. return -1;
  730. }
  731. return 0;
  732. }
  733. int cmake::LocalGenerate()
  734. {
  735. // Read in the cache
  736. m_CacheManager->LoadCache(this->GetHomeOutputDirectory());
  737. // create the generator based on the cache if it isn't already there
  738. const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
  739. if(genName)
  740. {
  741. m_GlobalGenerator = this->CreateGlobalGenerator(genName);
  742. }
  743. else
  744. {
  745. cmSystemTools::Error("Could local Generate called without the GENERATOR being specified in the CMakeCache");
  746. return -1;
  747. }
  748. // do the local generate
  749. m_GlobalGenerator->LocalGenerate();
  750. if(cmSystemTools::GetErrorOccuredFlag())
  751. {
  752. return -1;
  753. }
  754. return 0;
  755. }
  756. unsigned int cmake::GetMajorVersion()
  757. {
  758. return cmMakefile::GetMajorVersion();
  759. }
  760. unsigned int cmake::GetMinorVersion()
  761. {
  762. return cmMakefile::GetMinorVersion();
  763. }
  764. const char *cmake::GetReleaseVersion()
  765. {
  766. return cmMakefile::GetReleaseVersion();
  767. }
  768. const char* cmake::GetCacheDefinition(const char* name) const
  769. {
  770. return m_CacheManager->GetCacheValue(name);
  771. }
  772. int cmake::DumpDocumentationToFile(std::ostream& f)
  773. {
  774. // Loop over all registered commands and print out documentation
  775. const char *name;
  776. const char *terse;
  777. const char *full;
  778. char tmp[1024];
  779. sprintf(tmp,"Version %d.%d", cmake::GetMajorVersion(),
  780. cmake::GetMinorVersion());
  781. f << "<html>\n";
  782. f << "<h1>Documentation for commands of CMake " << tmp << "</h1>\n";
  783. f << "<ul>\n";
  784. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  785. j != m_Commands.end(); ++j)
  786. {
  787. name = (*j).second->GetName();
  788. terse = (*j).second->GetTerseDocumentation();
  789. full = (*j).second->GetFullDocumentation();
  790. f << "<li><b>" << name << "</b> - " << terse << std::endl
  791. << "<br><i>Usage:</i> " << full << "</li>" << std::endl << std::endl;
  792. }
  793. f << "</ul></html>\n";
  794. return 1;
  795. }
  796. void cmake::AddDefaultCommands()
  797. {
  798. std::list<cmCommand*> commands;
  799. GetPredefinedCommands(commands);
  800. for(std::list<cmCommand*>::iterator i = commands.begin();
  801. i != commands.end(); ++i)
  802. {
  803. this->AddCommand(*i);
  804. }
  805. }