cmake.cxx 26 KB

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