cmake.cxx 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646
  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. #if defined(CMAKE_BUILD_WITH_CMAKE)
  21. # include "cmVariableWatch.h"
  22. # include "cmVersion.h"
  23. # include "cmLocalUnixMakefileGenerator2.h"
  24. #endif
  25. // only build kdevelop generator on non-windows platforms
  26. // when not bootstrapping cmake
  27. #if !defined(_WIN32)
  28. # if defined(CMAKE_BUILD_WITH_CMAKE)
  29. # define CMAKE_USE_KDEVELOP
  30. # endif
  31. #endif
  32. // include the generator
  33. #if defined(_WIN32) && !defined(__CYGWIN__)
  34. # include "cmGlobalVisualStudio6Generator.h"
  35. # if !defined(__MINGW32__)
  36. # include "cmGlobalVisualStudio7Generator.h"
  37. # include "cmGlobalVisualStudio71Generator.h"
  38. # include "cmGlobalVisualStudio8Generator.h"
  39. # endif
  40. # include "cmGlobalBorlandMakefileGenerator.h"
  41. # include "cmGlobalNMakeMakefileGenerator.h"
  42. # include "cmWin32ProcessExecution.h"
  43. #else
  44. #endif
  45. #include "cmGlobalUnixMakefileGenerator.h"
  46. #ifdef CMAKE_USE_KDEVELOP
  47. # include "cmGlobalKdevelopGenerator.h"
  48. #endif
  49. #include <stdlib.h> // required for atoi
  50. #ifdef __APPLE__
  51. # include <sys/types.h>
  52. # include <sys/time.h>
  53. # include <sys/resource.h>
  54. # if defined(CMAKE_BUILD_WITH_CMAKE)
  55. # include "cmGlobalCodeWarriorGenerator.h"
  56. # endif
  57. #endif
  58. #include <memory> // auto_ptr
  59. void cmNeedBackwardsCompatibility(const std::string& variable,
  60. int access_type, void* )
  61. {
  62. #ifdef CMAKE_BUILD_WITH_CMAKE
  63. if (access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
  64. {
  65. std::string message = "An attempt was made to access a variable: ";
  66. message += variable;
  67. message += " that has not been defined. Some variables were always defined "
  68. "by CMake in versions prior to 1.6. To fix this you might need to set the "
  69. "cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If you are "
  70. "writing a CMakeList file, (or have already set "
  71. "CMAKE_BACKWARDS_COMPATABILITY to 1.4 or less) then you probably need to "
  72. "include a CMake module to test for the feature this variable defines.";
  73. cmSystemTools::Error(message.c_str());
  74. }
  75. #else
  76. (void)variable;
  77. (void)access_type;
  78. #endif
  79. }
  80. cmake::cmake()
  81. {
  82. m_DebugTryCompile = false;
  83. #ifdef __APPLE__
  84. struct rlimit rlp;
  85. if(!getrlimit(RLIMIT_STACK, &rlp))
  86. {
  87. if(rlp.rlim_cur != rlp.rlim_max)
  88. {
  89. rlp.rlim_cur = rlp.rlim_max;
  90. setrlimit(RLIMIT_STACK, &rlp);
  91. }
  92. }
  93. #endif
  94. // If MAKEFLAGS are given in the environment, remove the environment
  95. // variable. This will prevent try-compile from succeeding when it
  96. // should fail (if "-i" is an option). We cannot simply test
  97. // whether "-i" is given and remove it because some make programs
  98. // encode the MAKEFLAGS variable in a strange way.
  99. if(getenv("MAKEFLAGS"))
  100. {
  101. cmSystemTools::PutEnv("MAKEFLAGS=");
  102. }
  103. m_Local = false;
  104. m_Verbose = false;
  105. m_InTryCompile = false;
  106. m_CacheManager = new cmCacheManager;
  107. m_GlobalGenerator = 0;
  108. m_ProgressCallback = 0;
  109. m_ProgressCallbackClientData = 0;
  110. m_ScriptMode = false;
  111. #ifdef CMAKE_BUILD_WITH_CMAKE
  112. m_VariableWatch = new cmVariableWatch;
  113. m_VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN",
  114. cmNeedBackwardsCompatibility);
  115. m_VariableWatch->AddWatch("CMAKE_SIZEOF_INT",
  116. cmNeedBackwardsCompatibility);
  117. m_VariableWatch->AddWatch("CMAKE_X_LIBS",
  118. cmNeedBackwardsCompatibility);
  119. #endif
  120. this->AddDefaultGenerators();
  121. this->AddDefaultCommands();
  122. }
  123. cmake::~cmake()
  124. {
  125. delete m_CacheManager;
  126. if (m_GlobalGenerator)
  127. {
  128. delete m_GlobalGenerator;
  129. m_GlobalGenerator = 0;
  130. }
  131. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  132. j != m_Commands.end(); ++j)
  133. {
  134. delete (*j).second;
  135. }
  136. #ifdef CMAKE_BUILD_WITH_CMAKE
  137. delete m_VariableWatch;
  138. #endif
  139. }
  140. bool cmake::CommandExists(const char* name) const
  141. {
  142. return (m_Commands.find(name) != m_Commands.end());
  143. }
  144. cmCommand *cmake::GetCommand(const char *name)
  145. {
  146. cmCommand* rm = 0;
  147. RegisteredCommandsMap::iterator pos = m_Commands.find(name);
  148. if (pos != m_Commands.end())
  149. {
  150. rm = (*pos).second;
  151. }
  152. return rm;
  153. }
  154. void cmake::AddCommand(cmCommand* wg)
  155. {
  156. std::string name = wg->GetName();
  157. // if the command already exists, free the old one
  158. RegisteredCommandsMap::iterator pos = m_Commands.find(name);
  159. if (pos != m_Commands.end())
  160. {
  161. delete pos->second;
  162. m_Commands.erase(pos);
  163. }
  164. m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
  165. }
  166. // Parse the args
  167. bool cmake::SetCacheArgs(const std::vector<std::string>& args)
  168. {
  169. for(unsigned int i=1; i < args.size(); ++i)
  170. {
  171. std::string arg = args[i];
  172. if(arg.find("-D",0) == 0)
  173. {
  174. std::string entry = arg.substr(2);
  175. std::string var, value;
  176. cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
  177. if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type) ||
  178. cmCacheManager::ParseEntry(entry.c_str(), var, value))
  179. {
  180. this->m_CacheManager->AddCacheEntry(var.c_str(), value.c_str(),
  181. "No help, variable specified on the command line.",
  182. type);
  183. }
  184. else
  185. {
  186. std::cerr << "Parse error in command line argument: " << arg << "\n"
  187. << "Should be: VAR:type=value\n";
  188. cmSystemTools::Error("No cmake scrpt provided.");
  189. return false;
  190. }
  191. }
  192. else if(arg.find("-C",0) == 0)
  193. {
  194. std::string path = arg.substr(2);
  195. if ( path.size() == 0 )
  196. {
  197. cmSystemTools::Error("No initial cache file provided.");
  198. return false;
  199. }
  200. std::cerr << "loading initial cache file " << path.c_str() << "\n";
  201. this->ReadListFile(path.c_str());
  202. }
  203. else if(arg.find("-P",0) == 0)
  204. {
  205. i++;
  206. std::string path = args[i];
  207. if ( path.size() == 0 )
  208. {
  209. cmSystemTools::Error("No cmake scrpt provided.");
  210. return false;
  211. }
  212. std::cerr << "Running cmake script file " << path.c_str() << "\n";
  213. this->ReadListFile(path.c_str());
  214. }
  215. }
  216. return true;
  217. }
  218. void cmake::ReadListFile(const char *path)
  219. {
  220. // if a generator was not yet created, temporarily create one
  221. cmGlobalGenerator *gg = this->GetGlobalGenerator();
  222. bool created = false;
  223. // if a generator was not specified use a generic one
  224. if (!gg)
  225. {
  226. gg = new cmGlobalGenerator;
  227. gg->SetCMakeInstance(this);
  228. created = true;
  229. }
  230. // read in the list file to fill the cache
  231. if(path)
  232. {
  233. std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
  234. lg->SetGlobalGenerator(gg);
  235. if (!lg->GetMakefile()->ReadListFile(0, path))
  236. {
  237. std::cerr << "Error in reading cmake initial cache file:"
  238. << path << "\n";
  239. }
  240. }
  241. // free generic one if generated
  242. if (created)
  243. {
  244. delete gg;
  245. }
  246. }
  247. // Parse the args
  248. void cmake::SetArgs(const std::vector<std::string>& args)
  249. {
  250. m_Local = false;
  251. bool directoriesSet = false;
  252. for(unsigned int i=1; i < args.size(); ++i)
  253. {
  254. std::string arg = args[i];
  255. if(arg.find("-H",0) == 0)
  256. {
  257. directoriesSet = true;
  258. std::string path = arg.substr(2);
  259. path = cmSystemTools::CollapseFullPath(path.c_str());
  260. cmSystemTools::ConvertToUnixSlashes(path);
  261. this->SetHomeDirectory(path.c_str());
  262. }
  263. else if(arg.find("-S",0) == 0)
  264. {
  265. directoriesSet = true;
  266. m_Local = true;
  267. std::string path = arg.substr(2);
  268. path = cmSystemTools::CollapseFullPath(path.c_str());
  269. cmSystemTools::ConvertToUnixSlashes(path);
  270. this->SetStartDirectory(path.c_str());
  271. }
  272. else if(arg.find("-O",0) == 0)
  273. {
  274. directoriesSet = true;
  275. std::string path = arg.substr(2);
  276. path = cmSystemTools::CollapseFullPath(path.c_str());
  277. cmSystemTools::ConvertToUnixSlashes(path);
  278. this->SetStartOutputDirectory(path.c_str());
  279. }
  280. else if(arg.find("-B",0) == 0)
  281. {
  282. directoriesSet = true;
  283. std::string path = arg.substr(2);
  284. path = cmSystemTools::CollapseFullPath(path.c_str());
  285. cmSystemTools::ConvertToUnixSlashes(path);
  286. this->SetHomeOutputDirectory(path.c_str());
  287. }
  288. else if((i < args.size()-1) && (arg.find("--check-build-system",0) == 0))
  289. {
  290. m_CheckBuildSystem = args[++i];
  291. }
  292. else if(arg.find("-V",0) == 0)
  293. {
  294. m_Verbose = true;
  295. }
  296. else if(arg.find("-D",0) == 0)
  297. {
  298. // skip for now
  299. }
  300. else if(arg.find("-C",0) == 0)
  301. {
  302. // skip for now
  303. }
  304. else if(arg.find("--script",0) == 0)
  305. {
  306. // skip for now
  307. }
  308. else if(arg.find("--debug-trycompile",0) == 0)
  309. {
  310. std::cout << "debug trycompile on\n";
  311. this->DebugTryCompileOn();
  312. }
  313. else if(arg.find("-G",0) == 0)
  314. {
  315. std::string value = arg.substr(2);
  316. cmGlobalGenerator* gen =
  317. this->CreateGlobalGenerator(value.c_str());
  318. if(!gen)
  319. {
  320. cmSystemTools::Error("Could not create named generator ",
  321. value.c_str());
  322. }
  323. else
  324. {
  325. this->SetGlobalGenerator(gen);
  326. }
  327. }
  328. // no option assume it is the path to the source
  329. else
  330. {
  331. directoriesSet = true;
  332. this->SetDirectoriesFromFile(arg.c_str());
  333. }
  334. }
  335. if(!directoriesSet)
  336. {
  337. this->SetHomeOutputDirectory
  338. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  339. this->SetStartOutputDirectory
  340. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  341. this->SetHomeDirectory
  342. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  343. this->SetStartDirectory
  344. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  345. }
  346. if (!m_Local)
  347. {
  348. this->SetStartDirectory(this->GetHomeDirectory());
  349. this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
  350. }
  351. }
  352. //----------------------------------------------------------------------------
  353. void cmake::SetDirectoriesFromFile(const char* arg)
  354. {
  355. // Check if the argument refers to a CMakeCache.txt or
  356. // CMakeLists.txt file.
  357. std::string listPath;
  358. std::string cachePath;
  359. bool argIsFile = false;
  360. if(cmSystemTools::FileIsDirectory(arg))
  361. {
  362. std::string path = cmSystemTools::CollapseFullPath(arg);
  363. cmSystemTools::ConvertToUnixSlashes(path);
  364. std::string cacheFile = path;
  365. cacheFile += "/CMakeCache.txt";
  366. std::string listFile = path;
  367. listFile += "/CMakeLists.txt";
  368. if(cmSystemTools::FileExists(cacheFile.c_str()))
  369. {
  370. cachePath = path;
  371. }
  372. if(cmSystemTools::FileExists(listFile.c_str()))
  373. {
  374. listPath = path;
  375. }
  376. }
  377. else if(cmSystemTools::FileExists(arg))
  378. {
  379. argIsFile = true;
  380. std::string fullPath = cmSystemTools::CollapseFullPath(arg);
  381. std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
  382. name = cmSystemTools::LowerCase(name);
  383. if(name == "cmakecache.txt")
  384. {
  385. cachePath = cmSystemTools::GetFilenamePath(fullPath.c_str());
  386. }
  387. else if(name == "cmakelists.txt")
  388. {
  389. listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
  390. }
  391. }
  392. else
  393. {
  394. // Specified file or directory does not exist. Try to set things
  395. // up to produce a meaningful error message.
  396. std::string fullPath = cmSystemTools::CollapseFullPath(arg);
  397. std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
  398. name = cmSystemTools::LowerCase(name);
  399. if(name == "cmakecache.txt" || name == "cmakelists.txt")
  400. {
  401. argIsFile = true;
  402. listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
  403. }
  404. else
  405. {
  406. listPath = fullPath;
  407. }
  408. }
  409. // If there is a CMakeCache.txt file, use its settings.
  410. if(cachePath.length() > 0)
  411. {
  412. cmCacheManager* cachem = this->GetCacheManager();
  413. cmCacheManager::CacheIterator it = cachem->NewIterator();
  414. if(cachem->LoadCache(cachePath.c_str()) && it.Find("CMAKE_HOME_DIRECTORY"))
  415. {
  416. this->SetHomeOutputDirectory(cachePath.c_str());
  417. this->SetStartOutputDirectory(cachePath.c_str());
  418. this->SetHomeDirectory(it.GetValue());
  419. this->SetStartDirectory(it.GetValue());
  420. return;
  421. }
  422. }
  423. // If there is a CMakeLists.txt file, use it as the source tree.
  424. if(listPath.length() > 0)
  425. {
  426. this->SetHomeDirectory(listPath.c_str());
  427. this->SetStartDirectory(listPath.c_str());
  428. if(argIsFile)
  429. {
  430. // Source CMakeLists.txt file given. It was probably dropped
  431. // onto the executable in a GUI. Default to an in-source build.
  432. this->SetHomeOutputDirectory(listPath.c_str());
  433. this->SetStartOutputDirectory(listPath.c_str());
  434. }
  435. else
  436. {
  437. // Source directory given on command line. Use current working
  438. // directory as build tree.
  439. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  440. this->SetHomeOutputDirectory(cwd.c_str());
  441. this->SetStartOutputDirectory(cwd.c_str());
  442. }
  443. return;
  444. }
  445. // We didn't find a CMakeLists.txt or CMakeCache.txt file from the
  446. // argument. Assume it is the path to the source tree, and use the
  447. // current working directory as the build tree.
  448. std::string full = cmSystemTools::CollapseFullPath(arg);
  449. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  450. this->SetHomeDirectory(full.c_str());
  451. this->SetStartDirectory(full.c_str());
  452. this->SetHomeOutputDirectory(cwd.c_str());
  453. this->SetStartOutputDirectory(cwd.c_str());
  454. }
  455. // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache
  456. int cmake::AddCMakePaths(const char *arg0)
  457. {
  458. // Find our own executable.
  459. std::vector<cmStdString> failures;
  460. std::string cMakeSelf = arg0;
  461. cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
  462. failures.push_back(cMakeSelf);
  463. cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str());
  464. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  465. {
  466. #ifdef CMAKE_BUILD_DIR
  467. std::string intdir = ".";
  468. #ifdef CMAKE_INTDIR
  469. intdir = CMAKE_INTDIR;
  470. #endif
  471. cMakeSelf = CMAKE_BUILD_DIR;
  472. cMakeSelf += "/bin/";
  473. cMakeSelf += intdir;
  474. cMakeSelf += "/cmake";
  475. cMakeSelf += cmSystemTools::GetExecutableExtension();
  476. #endif
  477. }
  478. #ifdef CMAKE_PREFIX
  479. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  480. {
  481. failures.push_back(cMakeSelf);
  482. cMakeSelf = CMAKE_PREFIX "/bin/cmake";
  483. }
  484. #endif
  485. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  486. {
  487. failures.push_back(cMakeSelf);
  488. cmOStringStream msg;
  489. msg << "CMAKE can not find the command line program cmake.\n";
  490. msg << " argv[0] = \"" << arg0 << "\"\n";
  491. msg << " Attempted paths:\n";
  492. std::vector<cmStdString>::iterator i;
  493. for(i=failures.begin(); i != failures.end(); ++i)
  494. {
  495. msg << " \"" << i->c_str() << "\"\n";
  496. }
  497. cmSystemTools::Error(msg.str().c_str());
  498. return 0;
  499. }
  500. // Save the value in the cache
  501. this->m_CacheManager->AddCacheEntry
  502. ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.",
  503. cmCacheManager::INTERNAL);
  504. // Find and save the command to edit the cache
  505. std::string editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  506. "/ccmake" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  507. if( !cmSystemTools::FileExists(editCacheCommand.c_str()))
  508. {
  509. editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  510. "/CMakeSetup" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  511. }
  512. std::string ctestCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  513. "/ctest" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  514. if(cmSystemTools::FileExists(ctestCommand.c_str()))
  515. {
  516. this->m_CacheManager->AddCacheEntry
  517. ("CMAKE_CTEST_COMMAND", ctestCommand.c_str(),
  518. "Path to ctest program executable.", cmCacheManager::INTERNAL);
  519. }
  520. if(cmSystemTools::FileExists(editCacheCommand.c_str()))
  521. {
  522. this->m_CacheManager->AddCacheEntry
  523. ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
  524. "Path to cache edit program executable.", cmCacheManager::INTERNAL);
  525. }
  526. // do CMAKE_ROOT, look for the environment variable first
  527. std::string cMakeRoot;
  528. std::string modules;
  529. if (getenv("CMAKE_ROOT"))
  530. {
  531. cMakeRoot = getenv("CMAKE_ROOT");
  532. modules = cMakeRoot + "/Modules/CMake.cmake";
  533. }
  534. if(!cmSystemTools::FileExists(modules.c_str()))
  535. {
  536. // next try exe/..
  537. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  538. std::string::size_type slashPos = cMakeRoot.rfind("/");
  539. if(slashPos != std::string::npos)
  540. {
  541. cMakeRoot = cMakeRoot.substr(0, slashPos);
  542. }
  543. // is there no Modules direcory there?
  544. modules = cMakeRoot + "/Modules/CMake.cmake";
  545. }
  546. if (!cmSystemTools::FileExists(modules.c_str()))
  547. {
  548. // try exe/../share/cmake
  549. cMakeRoot += CMAKE_DATA_DIR;
  550. modules = cMakeRoot + "/Modules/CMake.cmake";
  551. }
  552. #ifdef CMAKE_ROOT_DIR
  553. if (!cmSystemTools::FileExists(modules.c_str()))
  554. {
  555. // try compiled in root directory
  556. cMakeRoot = CMAKE_ROOT_DIR;
  557. modules = cMakeRoot + "/Modules/CMake.cmake";
  558. }
  559. #endif
  560. #ifdef CMAKE_PREFIX
  561. if (!cmSystemTools::FileExists(modules.c_str()))
  562. {
  563. // try compiled in install prefix
  564. cMakeRoot = CMAKE_PREFIX CMAKE_DATA_DIR;
  565. modules = cMakeRoot + "/Modules/CMake.cmake";
  566. }
  567. #endif
  568. if (!cmSystemTools::FileExists(modules.c_str()))
  569. {
  570. // try
  571. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  572. cMakeRoot += CMAKE_DATA_DIR;
  573. modules = cMakeRoot + "/Modules/CMake.cmake";
  574. }
  575. if(!cmSystemTools::FileExists(modules.c_str()))
  576. {
  577. // next try exe
  578. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  579. // is there no Modules direcory there?
  580. modules = cMakeRoot + "/Modules/CMake.cmake";
  581. }
  582. if (!cmSystemTools::FileExists(modules.c_str()))
  583. {
  584. // couldn't find modules
  585. cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n"
  586. "CMake has most likely not been installed correctly.\n"
  587. "Modules directory not found in\n",
  588. cMakeRoot.c_str());
  589. return 0;
  590. }
  591. this->m_CacheManager->AddCacheEntry
  592. ("CMAKE_ROOT", cMakeRoot.c_str(),
  593. "Path to CMake installation.", cmCacheManager::INTERNAL);
  594. #ifdef _WIN32
  595. std::string comspec = "cmw9xcom.exe";
  596. cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
  597. #endif
  598. return 1;
  599. }
  600. void CMakeCommandUsage(const char* program)
  601. {
  602. cmOStringStream errorStream;
  603. #ifdef CMAKE_BUILD_WITH_CMAKE
  604. errorStream
  605. << "cmake version " << cmVersion::GetCMakeVersion() << "\n";
  606. #else
  607. errorStream
  608. << "cmake bootstrap\n";
  609. #endif
  610. errorStream
  611. << "Usage: " << program << " -E [command] [arguments ...]\n"
  612. << "Available commands: \n"
  613. << " chdir dir cmd [args]... - run command in a given directory\n"
  614. << " copy file destination - copy file to destination (either file or directory)\n"
  615. << " copy_if_different in-file out-file - copy file if input has changed\n"
  616. << " echo [string]... - displays arguments as text\n"
  617. << " remove file1 file2 ... - remove the file(s)\n"
  618. << " time command [args] ... - run command and return elapsed time\n";
  619. #if defined(_WIN32) && !defined(__CYGWIN__)
  620. errorStream
  621. << " write_regv key value - write registry value\n"
  622. << " delete_regv key - delete registry value\n"
  623. << " comspec - on windows 9x use this for RunCommand\n";
  624. #endif
  625. cmSystemTools::Error(errorStream.str().c_str());
  626. }
  627. int cmake::CMakeCommand(std::vector<std::string>& args)
  628. {
  629. if (args.size() > 1)
  630. {
  631. // Copy file
  632. if (args[1] == "copy" && args.size() == 4)
  633. {
  634. if(!cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str()))
  635. {
  636. std::cerr << "Error copying file \"" << args[2].c_str()
  637. << "\" to \"" << args[3].c_str() << "\".\n";
  638. return 1;
  639. }
  640. return 0;
  641. }
  642. // Copy file if different.
  643. if (args[1] == "copy_if_different" && args.size() == 4)
  644. {
  645. if(!cmSystemTools::CopyFileIfDifferent(args[2].c_str(), args[3].c_str()))
  646. {
  647. std::cerr << "Error copying file (if different) from \""
  648. << args[2].c_str() << "\" to \"" << args[3].c_str()
  649. << "\".\n";
  650. return 1;
  651. }
  652. return 0;
  653. }
  654. // Echo string
  655. else if (args[1] == "echo" )
  656. {
  657. unsigned int cc;
  658. for ( cc = 2; cc < args.size(); cc ++ )
  659. {
  660. std::cout << args[cc] << " ";
  661. }
  662. std::cout << std::endl;
  663. return 0;
  664. }
  665. // Remove file
  666. else if (args[1] == "remove" && args.size() > 2)
  667. {
  668. for (std::string::size_type cc = 2; cc < args.size(); cc ++)
  669. {
  670. if(args[cc] != "-f")
  671. {
  672. if(args[cc] == "\\-f")
  673. {
  674. args[cc] = "-f";
  675. }
  676. cmSystemTools::RemoveFile(args[cc].c_str());
  677. }
  678. }
  679. return 0;
  680. }
  681. // Clock command
  682. else if (args[1] == "time" && args.size() > 2)
  683. {
  684. std::string command = args[2];
  685. for (std::string::size_type cc = 3; cc < args.size(); cc ++)
  686. {
  687. command += " ";
  688. command += args[cc];
  689. }
  690. clock_t clock_start, clock_finish;
  691. time_t time_start, time_finish;
  692. time(&time_start);
  693. clock_start = clock();
  694. cmSystemTools::RunSingleCommand(command.c_str());
  695. clock_finish = clock();
  696. time(&time_finish);
  697. double clocks_per_sec = (double)CLOCKS_PER_SEC;
  698. std::cout << "Elapsed time: "
  699. << (long)(time_finish - time_start) << " s. (time)"
  700. << ", "
  701. << (double)(clock_finish - clock_start) / clocks_per_sec
  702. << " s. (clock)"
  703. << "\n";
  704. return 0;
  705. }
  706. // Clock command
  707. else if (args[1] == "chdir" && args.size() >= 4)
  708. {
  709. std::string directory = args[2];
  710. std::string command = "\"";
  711. command += args[3];
  712. command += "\"";
  713. for (std::string::size_type cc = 4; cc < args.size(); cc ++)
  714. {
  715. command += " \"";
  716. command += args[cc];
  717. command += "\"";
  718. }
  719. int retval = 0;
  720. int timeout = 0;
  721. if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval,
  722. directory.c_str(), true, timeout) )
  723. {
  724. return retval;
  725. }
  726. return 1;
  727. }
  728. // Internal CMake shared library support.
  729. else if (args[1] == "cmake_symlink_library" && args.size() == 5)
  730. {
  731. int result = 0;
  732. std::string realName = args[2];
  733. std::string soName = args[3];
  734. std::string name = args[4];
  735. if(soName != realName)
  736. {
  737. std::string fname = cmSystemTools::GetFilenameName(realName);
  738. if(cmSystemTools::FileExists(soName.c_str()))
  739. {
  740. cmSystemTools::RemoveFile(soName.c_str());
  741. }
  742. if(!cmSystemTools::CreateSymlink(fname.c_str(), soName.c_str()))
  743. {
  744. result = 1;
  745. }
  746. }
  747. if(name != soName)
  748. {
  749. std::string fname = cmSystemTools::GetFilenameName(soName);
  750. if(cmSystemTools::FileExists(soName.c_str()))
  751. {
  752. cmSystemTools::RemoveFile(name.c_str());
  753. }
  754. if(!cmSystemTools::CreateSymlink(fname.c_str(), name.c_str()))
  755. {
  756. result = 1;
  757. }
  758. }
  759. return result;
  760. }
  761. #ifdef CMAKE_BUILD_WITH_CMAKE
  762. // Internal CMake dependency scanning support.
  763. else if (args[1] == "cmake_depends" && args.size() >= 5)
  764. {
  765. return cmLocalUnixMakefileGenerator2::ScanDependencies(args)? 0 : 1;
  766. }
  767. #endif
  768. #if defined(_WIN32) && !defined(__CYGWIN__)
  769. // Write registry value
  770. else if (args[1] == "write_regv" && args.size() > 3)
  771. {
  772. return cmSystemTools::WriteRegistryValue(args[2].c_str(),
  773. args[3].c_str()) ? 0 : 1;
  774. }
  775. // Delete registry value
  776. else if (args[1] == "delete_regv" && args.size() > 2)
  777. {
  778. return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
  779. }
  780. // Remove file
  781. else if (args[1] == "comspec" && args.size() > 2)
  782. {
  783. unsigned int cc;
  784. std::string command = args[2];
  785. for ( cc = 3; cc < args.size(); cc ++ )
  786. {
  787. command += " " + args[cc];
  788. }
  789. return cmWin32ProcessExecution::Windows9xHack(command.c_str());
  790. }
  791. #endif
  792. }
  793. ::CMakeCommandUsage(args[0].c_str());
  794. return 1;
  795. }
  796. void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
  797. {
  798. for(RegisteredGeneratorsMap::const_iterator i = m_Generators.begin();
  799. i != m_Generators.end(); ++i)
  800. {
  801. names.push_back(i->first);
  802. }
  803. }
  804. cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
  805. {
  806. RegisteredGeneratorsMap::const_iterator i = m_Generators.find(name);
  807. if(i != m_Generators.end())
  808. {
  809. cmGlobalGenerator* generator = (i->second)();
  810. generator->SetCMakeInstance(this);
  811. return generator;
  812. }
  813. else
  814. {
  815. return 0;
  816. }
  817. }
  818. void cmake::SetHomeDirectory(const char* dir)
  819. {
  820. m_cmHomeDirectory = dir;
  821. cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory);
  822. }
  823. void cmake::SetHomeOutputDirectory(const char* lib)
  824. {
  825. m_HomeOutputDirectory = lib;
  826. cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory);
  827. }
  828. void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
  829. {
  830. // delete the old generator
  831. if (m_GlobalGenerator)
  832. {
  833. delete m_GlobalGenerator;
  834. // restore the original environment variables CXX and CC
  835. // Restor CC
  836. std::string env = "CC=";
  837. if(m_CCEnvironment.size())
  838. {
  839. env += m_CCEnvironment;
  840. }
  841. cmSystemTools::PutEnv(env.c_str());
  842. env = "CXX=";
  843. if(m_CXXEnvironment.size())
  844. {
  845. env += m_CXXEnvironment;
  846. }
  847. cmSystemTools::PutEnv(env.c_str());
  848. }
  849. // set the new
  850. m_GlobalGenerator = gg;
  851. // set the global flag for unix style paths on cmSystemTools as
  852. // soon as the generator is set. This allows gmake to be used
  853. // on windows.
  854. cmSystemTools::SetForceUnixPaths(m_GlobalGenerator->GetForceUnixPaths());
  855. // Save the environment variables CXX and CC
  856. const char* cxx = getenv("CXX");
  857. const char* cc = getenv("CC");
  858. if(cxx)
  859. {
  860. m_CXXEnvironment = cxx;
  861. }
  862. else
  863. {
  864. m_CXXEnvironment = "";
  865. }
  866. if(cc)
  867. {
  868. m_CCEnvironment = cc;
  869. }
  870. else
  871. {
  872. m_CCEnvironment = "";
  873. }
  874. // set the cmake instance just to be sure
  875. gg->SetCMakeInstance(this);
  876. }
  877. int cmake::DoPreConfigureChecks()
  878. {
  879. // Make sure the Start directory contains a CMakeLists.txt file.
  880. std::string srcList = this->GetHomeDirectory();
  881. srcList += "/CMakeLists.txt";
  882. if(!cmSystemTools::FileExists(srcList.c_str()))
  883. {
  884. cmOStringStream err;
  885. if(cmSystemTools::FileIsDirectory(this->GetHomeDirectory()))
  886. {
  887. err << "The source directory \"" << this->GetHomeDirectory()
  888. << "\" does not appear to contain CMakeLists.txt.\n";
  889. }
  890. else if(cmSystemTools::FileExists(this->GetHomeDirectory()))
  891. {
  892. err << "The source directory \"" << this->GetHomeDirectory()
  893. << "\" is a file, not a directory.\n";
  894. }
  895. else
  896. {
  897. err << "The source directory \"" << this->GetHomeDirectory()
  898. << "\" does not exist.\n";
  899. }
  900. err << "Specify --help for usage, or press the help button on the CMake GUI.";
  901. cmSystemTools::Error(err.str().c_str());
  902. return -2;
  903. }
  904. // do a sanity check on some values
  905. if(m_CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
  906. {
  907. std::string cacheStart =
  908. m_CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
  909. cacheStart += "/CMakeLists.txt";
  910. std::string currentStart = this->GetHomeDirectory();
  911. currentStart += "/CMakeLists.txt";
  912. if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
  913. {
  914. std::string message = "The source \"";
  915. message += currentStart;
  916. message += "\" does not match the source \"";
  917. message += cacheStart;
  918. message += "\" used to generate cache. ";
  919. message += "Re-run cmake with a different source directory.";
  920. cmSystemTools::Error(message.c_str());
  921. return -2;
  922. }
  923. }
  924. else
  925. {
  926. return 0;
  927. }
  928. return 1;
  929. }
  930. int cmake::Configure()
  931. {
  932. // Construct right now our path conversion table before it's too late:
  933. this->UpdateConversionPathTable();
  934. int res = 0;
  935. if ( !m_ScriptMode )
  936. {
  937. res = this->DoPreConfigureChecks();
  938. }
  939. if ( res < 0 )
  940. {
  941. return -2;
  942. }
  943. if ( !res )
  944. {
  945. m_CacheManager->AddCacheEntry("CMAKE_HOME_DIRECTORY",
  946. this->GetHomeDirectory(),
  947. "Start directory with the top level CMakeLists.txt file for this project",
  948. cmCacheManager::INTERNAL);
  949. }
  950. // set the default BACKWARDS compatibility to the current version
  951. if(!m_CacheManager->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
  952. {
  953. char ver[256];
  954. sprintf(ver,"%i.%i",cmMakefile::GetMajorVersion(),
  955. cmMakefile::GetMinorVersion());
  956. this->m_CacheManager->AddCacheEntry
  957. ("CMAKE_BACKWARDS_COMPATIBILITY",ver,
  958. "For backwards compatibility, what version of CMake commands and syntax should this version of CMake allow.",
  959. cmCacheManager::STRING);
  960. }
  961. // no generator specified on the command line
  962. if(!m_GlobalGenerator)
  963. {
  964. const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
  965. if(genName)
  966. {
  967. m_GlobalGenerator = this->CreateGlobalGenerator(genName);
  968. }
  969. if(m_GlobalGenerator)
  970. {
  971. // set the global flag for unix style paths on cmSystemTools as
  972. // soon as the generator is set. This allows gmake to be used
  973. // on windows.
  974. cmSystemTools::SetForceUnixPaths(m_GlobalGenerator->GetForceUnixPaths());
  975. }
  976. else
  977. {
  978. #if defined(__BORLANDC__) && defined(_WIN32)
  979. this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
  980. #elif defined(_WIN32) && !defined(__CYGWIN__)
  981. std::string installedCompiler;
  982. std::string mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup;Dbghelp_path]";
  983. cmSystemTools::ExpandRegistryValues(mp);
  984. if (!(mp == "/registry"))
  985. {
  986. installedCompiler = "Visual Studio 8 2005";
  987. }
  988. else
  989. {
  990. mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1;InstallDir]";
  991. cmSystemTools::ExpandRegistryValues(mp);
  992. if (!(mp == "/registry"))
  993. {
  994. installedCompiler = "Visual Studio 7 .NET 2003";
  995. }
  996. else
  997. {
  998. mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.0;InstallDir]";
  999. cmSystemTools::ExpandRegistryValues(mp);
  1000. if (!(mp == "/registry"))
  1001. {
  1002. installedCompiler = "Visual Studio 7";
  1003. }
  1004. else
  1005. {
  1006. installedCompiler = "Visual Studio 6";
  1007. }
  1008. }
  1009. }
  1010. cmGlobalGenerator* gen = this->CreateGlobalGenerator(installedCompiler.c_str());
  1011. if(!gen)
  1012. {
  1013. gen = new cmGlobalNMakeMakefileGenerator;
  1014. }
  1015. this->SetGlobalGenerator(gen);
  1016. #else
  1017. this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator);
  1018. #endif
  1019. }
  1020. if(!m_GlobalGenerator)
  1021. {
  1022. cmSystemTools::Error("Could not create generator");
  1023. return -1;
  1024. }
  1025. }
  1026. const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
  1027. if(genName)
  1028. {
  1029. if(strcmp(m_GlobalGenerator->GetName(), genName) != 0)
  1030. {
  1031. std::string message = "Error: generator : ";
  1032. message += m_GlobalGenerator->GetName();
  1033. message += "\nDoes not match the generator used previously: ";
  1034. message += genName;
  1035. message +=
  1036. "\nEither remove the CMakeCache.txt file or choose a different"
  1037. " binary directory.";
  1038. cmSystemTools::Error(message.c_str());
  1039. return -2;
  1040. }
  1041. }
  1042. if(!m_CacheManager->GetCacheValue("CMAKE_GENERATOR"))
  1043. {
  1044. m_CacheManager->AddCacheEntry("CMAKE_GENERATOR", m_GlobalGenerator->GetName(),
  1045. "Name of generator.",
  1046. cmCacheManager::INTERNAL);
  1047. }
  1048. // reset any system configuration information, except for when we are
  1049. // InTryCompile. With TryCompile the system info is taken from the parent's
  1050. // info to save time
  1051. if (!m_InTryCompile)
  1052. {
  1053. m_GlobalGenerator->ClearEnabledLanguages();
  1054. }
  1055. this->CleanupWrittenFiles();
  1056. // actually do the configure
  1057. m_GlobalGenerator->Configure();
  1058. // Before saving the cache
  1059. // if the project did not define one of the entries below, add them now
  1060. // so users can edit the values in the cache:
  1061. // LIBRARY_OUTPUT_PATH
  1062. // EXECUTABLE_OUTPUT_PATH
  1063. if(!m_CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH"))
  1064. {
  1065. m_CacheManager->AddCacheEntry("LIBRARY_OUTPUT_PATH", "",
  1066. "Single output directory for building all libraries.",
  1067. cmCacheManager::PATH);
  1068. }
  1069. if(!m_CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
  1070. {
  1071. m_CacheManager->AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "",
  1072. "Single output directory for building all executables.",
  1073. cmCacheManager::PATH);
  1074. }
  1075. if(!m_CacheManager->GetCacheValue("CMAKE_USE_RELATIVE_PATHS"))
  1076. {
  1077. m_CacheManager->AddCacheEntry("CMAKE_USE_RELATIVE_PATHS", false,
  1078. "If true, cmake will use relative paths in makefiles and projects.");
  1079. cmCacheManager::CacheIterator it =
  1080. m_CacheManager->GetCacheIterator("CMAKE_USE_RELATIVE_PATHS");
  1081. if ( !it.PropertyExists("ADVANCED") )
  1082. {
  1083. it.SetProperty("ADVANCED", "1");
  1084. }
  1085. }
  1086. if(cmSystemTools::GetFatalErrorOccured() &&
  1087. (!this->m_CacheManager->GetCacheValue("CMAKE_MAKE_PROGRAM") ||
  1088. cmSystemTools::IsOff(this->m_CacheManager->GetCacheValue("CMAKE_MAKE_PROGRAM"))))
  1089. {
  1090. // We must have a bad generator selection. Wipe the cache entry so the
  1091. // user can select another.
  1092. m_CacheManager->RemoveCacheEntry("CMAKE_GENERATOR");
  1093. }
  1094. if ( !m_ScriptMode )
  1095. {
  1096. this->m_CacheManager->SaveCache(this->GetHomeOutputDirectory());
  1097. }
  1098. if(cmSystemTools::GetErrorOccuredFlag())
  1099. {
  1100. return -1;
  1101. }
  1102. return 0;
  1103. }
  1104. bool cmake::CacheVersionMatches()
  1105. {
  1106. const char* majv = m_CacheManager->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION");
  1107. const char* minv = m_CacheManager->GetCacheValue("CMAKE_CACHE_MINOR_VERSION");
  1108. const char* relv = m_CacheManager->GetCacheValue("CMAKE_CACHE_RELEASE_VERSION");
  1109. bool cacheSameCMake = false;
  1110. if(majv &&
  1111. atoi(majv) == static_cast<int>(cmMakefile::GetMajorVersion())
  1112. && minv &&
  1113. atoi(minv) == static_cast<int>(cmMakefile::GetMinorVersion())
  1114. && relv && (strcmp(relv, cmMakefile::GetReleaseVersion()) == 0))
  1115. {
  1116. cacheSameCMake = true;
  1117. }
  1118. return cacheSameCMake;
  1119. }
  1120. void cmake::PreLoadCMakeFiles()
  1121. {
  1122. std::string pre_load = this->GetHomeDirectory();
  1123. if ( pre_load.size() > 0 )
  1124. {
  1125. pre_load += "/PreLoad.cmake";
  1126. if ( cmSystemTools::FileExists(pre_load.c_str()) )
  1127. {
  1128. this->ReadListFile(pre_load.c_str());
  1129. }
  1130. }
  1131. pre_load = this->GetHomeOutputDirectory();
  1132. if ( pre_load.size() > 0 )
  1133. {
  1134. pre_load += "/PreLoad.cmake";
  1135. if ( cmSystemTools::FileExists(pre_load.c_str()) )
  1136. {
  1137. this->ReadListFile(pre_load.c_str());
  1138. }
  1139. }
  1140. }
  1141. // handle a command line invocation
  1142. int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
  1143. {
  1144. // Process the arguments
  1145. this->SetArgs(args);
  1146. // set the cmake command
  1147. m_CMakeCommand = args[0];
  1148. if ( !m_ScriptMode )
  1149. {
  1150. // load the cache
  1151. if(this->LoadCache() < 0)
  1152. {
  1153. cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n");
  1154. return -1;
  1155. }
  1156. }
  1157. // Add any cache args
  1158. if ( !this->SetCacheArgs(args) )
  1159. {
  1160. cmSystemTools::Error("Problem processing arguments. Aborting.\n");
  1161. return -1;
  1162. }
  1163. this->PreLoadCMakeFiles();
  1164. std::string systemFile = this->GetHomeOutputDirectory();
  1165. systemFile += "/CMakeSystem.cmake";
  1166. if ( noconfigure )
  1167. {
  1168. return 0;
  1169. }
  1170. int ret = 0;
  1171. // if not local or the cmake version has changed since the last run
  1172. // of cmake, or CMakeSystem.cmake file is not in the root binary
  1173. // directory, run a global generate
  1174. if(m_ScriptMode || !m_Local || !this->CacheVersionMatches() ||
  1175. !cmSystemTools::FileExists(systemFile.c_str()) )
  1176. {
  1177. // Check the state of the build system to see if we need to regenerate.
  1178. if(!this->CheckBuildSystem())
  1179. {
  1180. return 0;
  1181. }
  1182. // If we are doing global generate, we better set start and start
  1183. // output directory to the root of the project.
  1184. std::string oldstartdir = this->GetStartDirectory();
  1185. std::string oldstartoutputdir = this->GetStartOutputDirectory();
  1186. this->SetStartDirectory(this->GetHomeDirectory());
  1187. this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
  1188. bool saveLocalFlag = m_Local;
  1189. m_Local = false;
  1190. ret = this->Configure();
  1191. if (ret || m_ScriptMode)
  1192. {
  1193. return ret;
  1194. }
  1195. ret = this->Generate();
  1196. std::string message = "Build files have been written to: ";
  1197. message += this->GetHomeOutputDirectory();
  1198. this->UpdateProgress(message.c_str(), -1);
  1199. if(ret)
  1200. {
  1201. return ret;
  1202. }
  1203. m_Local = saveLocalFlag;
  1204. this->SetStartDirectory(oldstartdir.c_str());
  1205. this->SetStartOutputDirectory(oldstartoutputdir.c_str());
  1206. }
  1207. // if we are local do the local thing
  1208. if (m_Local)
  1209. {
  1210. ret = this->LocalGenerate();
  1211. }
  1212. return ret;
  1213. }
  1214. int cmake::Generate()
  1215. {
  1216. if(!m_GlobalGenerator)
  1217. {
  1218. return -1;
  1219. }
  1220. m_GlobalGenerator->Generate();
  1221. if(cmSystemTools::GetErrorOccuredFlag())
  1222. {
  1223. return -1;
  1224. }
  1225. return 0;
  1226. }
  1227. int cmake::LocalGenerate()
  1228. {
  1229. // Read in the cache
  1230. m_CacheManager->LoadCache(this->GetHomeOutputDirectory());
  1231. // create the generator based on the cache if it isn't already there
  1232. const char* genName = m_CacheManager->GetCacheValue("CMAKE_GENERATOR");
  1233. if(genName)
  1234. {
  1235. m_GlobalGenerator = this->CreateGlobalGenerator(genName);
  1236. // set the global flag for unix style paths on cmSystemTools as
  1237. // soon as the generator is set. This allows gmake to be used
  1238. // on windows.
  1239. cmSystemTools::SetForceUnixPaths(m_GlobalGenerator->GetForceUnixPaths());
  1240. }
  1241. else
  1242. {
  1243. cmSystemTools::Error("Could local Generate called without the GENERATOR being specified in the CMakeCache");
  1244. return -1;
  1245. }
  1246. // do the local generate
  1247. m_GlobalGenerator->LocalGenerate();
  1248. if(cmSystemTools::GetErrorOccuredFlag())
  1249. {
  1250. return -1;
  1251. }
  1252. return 0;
  1253. }
  1254. unsigned int cmake::GetMajorVersion()
  1255. {
  1256. return cmMakefile::GetMajorVersion();
  1257. }
  1258. unsigned int cmake::GetMinorVersion()
  1259. {
  1260. return cmMakefile::GetMinorVersion();
  1261. }
  1262. const char *cmake::GetReleaseVersion()
  1263. {
  1264. return cmMakefile::GetReleaseVersion();
  1265. }
  1266. void cmake::AddCacheEntry(const char* key, const char* value,
  1267. const char* helpString,
  1268. int type)
  1269. {
  1270. m_CacheManager->AddCacheEntry(key, value,
  1271. helpString,
  1272. cmCacheManager::CacheEntryType(type));
  1273. }
  1274. const char* cmake::GetCacheDefinition(const char* name) const
  1275. {
  1276. return m_CacheManager->GetCacheValue(name);
  1277. }
  1278. int cmake::DumpDocumentationToFile(std::ostream& f)
  1279. {
  1280. #ifdef CMAKE_BUILD_WITH_CMAKE
  1281. // Loop over all registered commands and print out documentation
  1282. const char *name;
  1283. const char *terse;
  1284. const char *full;
  1285. char tmp[1024];
  1286. sprintf(tmp,"Version %d.%d (%s)", cmake::GetMajorVersion(),
  1287. cmake::GetMinorVersion(), cmVersion::GetReleaseVersion().c_str());
  1288. f << "<html>\n";
  1289. f << "<h1>Documentation for commands of CMake " << tmp << "</h1>\n";
  1290. f << "<ul>\n";
  1291. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  1292. j != m_Commands.end(); ++j)
  1293. {
  1294. name = (*j).second->GetName();
  1295. terse = (*j).second->GetTerseDocumentation();
  1296. full = (*j).second->GetFullDocumentation();
  1297. f << "<li><b>" << name << "</b> - " << terse << std::endl
  1298. << "<br><i>Usage:</i> " << full << "</li>" << std::endl << std::endl;
  1299. }
  1300. f << "</ul></html>\n";
  1301. #else
  1302. (void)f;
  1303. #endif
  1304. return 1;
  1305. }
  1306. void cmake::AddDefaultCommands()
  1307. {
  1308. std::list<cmCommand*> commands;
  1309. GetPredefinedCommands(commands);
  1310. for(std::list<cmCommand*>::iterator i = commands.begin();
  1311. i != commands.end(); ++i)
  1312. {
  1313. this->AddCommand(*i);
  1314. }
  1315. }
  1316. void cmake::AddDefaultGenerators()
  1317. {
  1318. #if defined(_WIN32) && !defined(__CYGWIN__)
  1319. m_Generators[cmGlobalVisualStudio6Generator::GetActualName()] =
  1320. &cmGlobalVisualStudio6Generator::New;
  1321. #if !defined(__MINGW32__)
  1322. m_Generators[cmGlobalVisualStudio7Generator::GetActualName()] =
  1323. &cmGlobalVisualStudio7Generator::New;
  1324. m_Generators[cmGlobalVisualStudio71Generator::GetActualName()] =
  1325. &cmGlobalVisualStudio71Generator::New;
  1326. m_Generators[cmGlobalVisualStudio8Generator::GetActualName()] =
  1327. &cmGlobalVisualStudio8Generator::New;
  1328. #endif
  1329. m_Generators[cmGlobalBorlandMakefileGenerator::GetActualName()] =
  1330. &cmGlobalBorlandMakefileGenerator::New;
  1331. m_Generators[cmGlobalNMakeMakefileGenerator::GetActualName()] =
  1332. &cmGlobalNMakeMakefileGenerator::New;
  1333. #else
  1334. # if defined(__APPLE__) && defined(CMAKE_BUILD_WITH_CMAKE)
  1335. m_Generators[cmGlobalCodeWarriorGenerator::GetActualName()] =
  1336. &cmGlobalCodeWarriorGenerator::New;
  1337. # endif
  1338. #endif
  1339. m_Generators[cmGlobalUnixMakefileGenerator::GetActualName()] =
  1340. &cmGlobalUnixMakefileGenerator::New;
  1341. #ifdef CMAKE_USE_KDEVELOP
  1342. m_Generators[cmGlobalKdevelopGenerator::GetActualName()] =
  1343. &cmGlobalKdevelopGenerator::New;
  1344. #endif
  1345. }
  1346. int cmake::LoadCache()
  1347. {
  1348. m_CacheManager->LoadCache(this->GetHomeOutputDirectory());
  1349. if (m_CMakeCommand.size() < 2)
  1350. {
  1351. cmSystemTools::Error("cmake command was not specified prior to loading the cache in cmake.cxx");
  1352. return -1;
  1353. }
  1354. // setup CMAKE_ROOT and CMAKE_COMMAND
  1355. if(!this->AddCMakePaths(m_CMakeCommand.c_str()))
  1356. {
  1357. return -3;
  1358. }
  1359. // set the default BACKWARDS compatibility to the current version
  1360. if(!m_CacheManager->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
  1361. {
  1362. char ver[256];
  1363. sprintf(ver,"%i.%i",cmMakefile::GetMajorVersion(),
  1364. cmMakefile::GetMinorVersion());
  1365. this->m_CacheManager->AddCacheEntry
  1366. ("CMAKE_BACKWARDS_COMPATIBILITY",ver,
  1367. "For backwards compatibility, what version of CMake commands and syntax should this version of CMake allow.",
  1368. cmCacheManager::STRING);
  1369. }
  1370. return 0;
  1371. }
  1372. void cmake::SetProgressCallback(ProgressCallback f, void *cd)
  1373. {
  1374. m_ProgressCallback = f;
  1375. m_ProgressCallbackClientData = cd;
  1376. }
  1377. void cmake::UpdateProgress(const char *msg, float prog)
  1378. {
  1379. if(m_ProgressCallback && !m_InTryCompile)
  1380. {
  1381. (*m_ProgressCallback)(msg, prog, m_ProgressCallbackClientData);
  1382. return;
  1383. }
  1384. }
  1385. void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v) const
  1386. {
  1387. for(RegisteredCommandsMap::const_iterator j = m_Commands.begin();
  1388. j != m_Commands.end(); ++j)
  1389. {
  1390. cmDocumentationEntry e =
  1391. {
  1392. (*j).second->GetName(),
  1393. (*j).second->GetTerseDocumentation(),
  1394. (*j).second->GetFullDocumentation()
  1395. };
  1396. v.push_back(e);
  1397. }
  1398. cmDocumentationEntry empty = {0,0,0};
  1399. v.push_back(empty);
  1400. }
  1401. void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
  1402. {
  1403. for(RegisteredGeneratorsMap::const_iterator i = m_Generators.begin();
  1404. i != m_Generators.end(); ++i)
  1405. {
  1406. cmDocumentationEntry e;
  1407. cmGlobalGenerator* generator = (i->second)();
  1408. generator->GetDocumentation(e);
  1409. delete generator;
  1410. v.push_back(e);
  1411. }
  1412. cmDocumentationEntry empty = {0,0,0};
  1413. v.push_back(empty);
  1414. }
  1415. void cmake::AddWrittenFile(const char* file)
  1416. {
  1417. m_WrittenFiles.insert(file);
  1418. }
  1419. bool cmake::HasWrittenFile(const char* file)
  1420. {
  1421. return m_WrittenFiles.find(file) != m_WrittenFiles.end();
  1422. }
  1423. void cmake::CleanupWrittenFiles()
  1424. {
  1425. m_WrittenFiles.clear();
  1426. }
  1427. void cmake::UpdateConversionPathTable()
  1428. {
  1429. // Update the path conversion table with any specified file:
  1430. const char* tablepath =
  1431. m_CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE");
  1432. if(tablepath)
  1433. {
  1434. std::ifstream table( tablepath );
  1435. if(!table)
  1436. {
  1437. cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", tablepath, ". CMake can not open file.");
  1438. cmSystemTools::ReportLastSystemError("CMake can not open file.");
  1439. }
  1440. else
  1441. {
  1442. std::string a, b;
  1443. while(!table.eof())
  1444. {
  1445. // two entries per line
  1446. table >> a; table >> b;
  1447. cmSystemTools::AddTranslationPath( a.c_str(), b.c_str());
  1448. }
  1449. }
  1450. }
  1451. }
  1452. //----------------------------------------------------------------------------
  1453. int cmake::CheckBuildSystem()
  1454. {
  1455. // This method will check the integrity of the build system if the
  1456. // option was given on the command line. It reads the given file to
  1457. // determine whether CMake should rerun. If it does rerun then the
  1458. // generation step will check the integrity of dependencies. If it
  1459. // does not then we need to check the integrity here.
  1460. // If no file is provided for the check, we have to rerun.
  1461. if(m_CheckBuildSystem.size() == 0)
  1462. {
  1463. return 1;
  1464. }
  1465. // If the file provided does not exist, we have to rerun.
  1466. if(!cmSystemTools::FileExists(m_CheckBuildSystem.c_str()))
  1467. {
  1468. return 1;
  1469. }
  1470. // Read the rerun check file and use it to decide whether to do the
  1471. // global generate.
  1472. cmake cm;
  1473. cmGlobalGenerator gg;
  1474. gg.SetCMakeInstance(&cm);
  1475. std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
  1476. lg->SetGlobalGenerator(&gg);
  1477. cmMakefile* mf = lg->GetMakefile();
  1478. if(!mf->ReadListFile(0, m_CheckBuildSystem.c_str()) ||
  1479. cmSystemTools::GetErrorOccuredFlag())
  1480. {
  1481. // There was an error reading the file. Just rerun.
  1482. return 1;
  1483. }
  1484. // Get the set of dependencies and outputs.
  1485. const char* dependsStr = mf->GetDefinition("CMAKE_MAKEFILE_DEPENDS");
  1486. const char* outputsStr = mf->GetDefinition("CMAKE_MAKEFILE_OUTPUTS");
  1487. if(!dependsStr || !outputsStr)
  1488. {
  1489. // Not enough information was provided to do the test. Just rerun.
  1490. return 1;
  1491. }
  1492. std::vector<std::string> depends;
  1493. std::vector<std::string> outputs;
  1494. cmSystemTools::ExpandListArgument(dependsStr, depends);
  1495. cmSystemTools::ExpandListArgument(outputsStr, outputs);
  1496. // If any output is older than any dependency then rerun.
  1497. for(std::vector<std::string>::iterator dep = depends.begin();
  1498. dep != depends.end(); ++dep)
  1499. {
  1500. for(std::vector<std::string>::iterator out = outputs.begin();
  1501. out != outputs.end(); ++out)
  1502. {
  1503. int result = 0;
  1504. if(!cmSystemTools::FileTimeCompare(out->c_str(), dep->c_str(), &result) ||
  1505. result < 0)
  1506. {
  1507. return 1;
  1508. }
  1509. }
  1510. }
  1511. #if defined(CMAKE_BUILD_WITH_CMAKE)
  1512. // We do not need to rerun CMake. Check dependency integrity.
  1513. if(const char* depCheck = mf->GetDefinition("CMAKE_DEPENDS_CHECK"))
  1514. {
  1515. cmLocalUnixMakefileGenerator2::CheckDependencies(depCheck);
  1516. }
  1517. #endif
  1518. // No need to rerun.
  1519. return 0;
  1520. }