cmake.cxx 23 KB

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