cmake.cxx 27 KB

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