cmake.cxx 25 KB

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