cmake.cxx 26 KB

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