cmake.cxx 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301
  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 "cmFileTimeComparison.h"
  21. #include "cmGeneratedFileStream.h"
  22. #if defined(CMAKE_BUILD_WITH_CMAKE)
  23. # include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
  24. # include "cmVariableWatch.h"
  25. # include "cmVersion.h"
  26. #endif
  27. // only build kdevelop generator on non-windows platforms
  28. // when not bootstrapping cmake
  29. #if !defined(_WIN32)
  30. # if defined(CMAKE_BUILD_WITH_CMAKE)
  31. # define CMAKE_USE_KDEVELOP
  32. # endif
  33. #endif
  34. #if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE)
  35. # define CMAKE_BOOT_MINGW
  36. #endif
  37. // include the generator
  38. #if defined(_WIN32) && !defined(__CYGWIN__)
  39. # if !defined(CMAKE_BOOT_MINGW)
  40. # include "cmGlobalVisualStudio6Generator.h"
  41. # include "cmGlobalVisualStudio7Generator.h"
  42. # include "cmGlobalVisualStudio71Generator.h"
  43. # include "cmGlobalVisualStudio8Generator.h"
  44. # include "cmGlobalBorlandMakefileGenerator.h"
  45. # include "cmGlobalNMakeMakefileGenerator.h"
  46. # include "cmGlobalWatcomWMakeGenerator.h"
  47. # endif
  48. # include "cmGlobalMSYSMakefileGenerator.h"
  49. # include "cmGlobalMinGWMakefileGenerator.h"
  50. # include "cmWin32ProcessExecution.h"
  51. #else
  52. #endif
  53. #include "cmGlobalUnixMakefileGenerator3.h"
  54. #ifdef CMAKE_USE_KDEVELOP
  55. # include "cmGlobalKdevelopGenerator.h"
  56. #endif
  57. #include <stdlib.h> // required for atoi
  58. #ifdef __APPLE__
  59. # include "cmGlobalXCodeGenerator.h"
  60. # define CMAKE_USE_XCODE 1
  61. # include <sys/types.h>
  62. # include <sys/time.h>
  63. # include <sys/resource.h>
  64. #endif
  65. #include <sys/stat.h> // struct stat
  66. #include <memory> // auto_ptr
  67. void cmNeedBackwardsCompatibility(const std::string& variable,
  68. int access_type, void* )
  69. {
  70. #ifdef CMAKE_BUILD_WITH_CMAKE
  71. if (access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
  72. {
  73. std::string message = "An attempt was made to access a variable: ";
  74. message += variable;
  75. message +=
  76. " that has not been defined. Some variables were always defined "
  77. "by CMake in versions prior to 1.6. To fix this you might need to set "
  78. "the cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If "
  79. "you are writing a CMakeList file, (or have already set "
  80. "CMAKE_BACKWARDS_COMPATABILITY to 1.4 or less) then you probably need "
  81. "to include a CMake module to test for the feature this variable "
  82. "defines.";
  83. cmSystemTools::Error(message.c_str());
  84. }
  85. #else
  86. (void)variable;
  87. (void)access_type;
  88. #endif
  89. }
  90. cmake::cmake()
  91. {
  92. this->DebugTryCompile = false;
  93. this->ClearBuildSystem = false;
  94. this->FileComparison = new cmFileTimeComparison;
  95. #ifdef __APPLE__
  96. struct rlimit rlp;
  97. if(!getrlimit(RLIMIT_STACK, &rlp))
  98. {
  99. if(rlp.rlim_cur != rlp.rlim_max)
  100. {
  101. rlp.rlim_cur = rlp.rlim_max;
  102. setrlimit(RLIMIT_STACK, &rlp);
  103. }
  104. }
  105. #endif
  106. // If MAKEFLAGS are given in the environment, remove the environment
  107. // variable. This will prevent try-compile from succeeding when it
  108. // should fail (if "-i" is an option). We cannot simply test
  109. // whether "-i" is given and remove it because some make programs
  110. // encode the MAKEFLAGS variable in a strange way.
  111. if(getenv("MAKEFLAGS"))
  112. {
  113. cmSystemTools::PutEnv("MAKEFLAGS=");
  114. }
  115. this->Verbose = false;
  116. this->InTryCompile = false;
  117. this->CacheManager = new cmCacheManager;
  118. this->GlobalGenerator = 0;
  119. this->ProgressCallback = 0;
  120. this->ProgressCallbackClientData = 0;
  121. this->ScriptMode = false;
  122. #ifdef CMAKE_BUILD_WITH_CMAKE
  123. this->VariableWatch = new cmVariableWatch;
  124. this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN",
  125. cmNeedBackwardsCompatibility);
  126. this->VariableWatch->AddWatch("CMAKE_SIZEOF_INT",
  127. cmNeedBackwardsCompatibility);
  128. this->VariableWatch->AddWatch("CMAKE_X_LIBS",
  129. cmNeedBackwardsCompatibility);
  130. #endif
  131. this->AddDefaultGenerators();
  132. this->AddDefaultCommands();
  133. // Make sure we can capture the build tool output.
  134. cmSystemTools::EnableVSConsoleOutput();
  135. }
  136. cmake::~cmake()
  137. {
  138. delete this->CacheManager;
  139. if (this->GlobalGenerator)
  140. {
  141. delete this->GlobalGenerator;
  142. this->GlobalGenerator = 0;
  143. }
  144. for(RegisteredCommandsMap::iterator j = this->Commands.begin();
  145. j != this->Commands.end(); ++j)
  146. {
  147. delete (*j).second;
  148. }
  149. #ifdef CMAKE_BUILD_WITH_CMAKE
  150. delete this->VariableWatch;
  151. #endif
  152. delete this->FileComparison;
  153. }
  154. void cmake::CleanupCommandsAndMacros()
  155. {
  156. std::vector<cmCommand*> commands;
  157. for(RegisteredCommandsMap::iterator j = this->Commands.begin();
  158. j != this->Commands.end(); ++j)
  159. {
  160. if ( !j->second->IsA("cmMacroHelperCommand") )
  161. {
  162. commands.push_back(j->second);
  163. }
  164. else
  165. {
  166. delete j->second;
  167. }
  168. }
  169. this->Commands.erase(this->Commands.begin(), this->Commands.end());
  170. std::vector<cmCommand*>::iterator it;
  171. for ( it = commands.begin(); it != commands.end();
  172. ++ it )
  173. {
  174. this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
  175. }
  176. }
  177. bool cmake::CommandExists(const char* name) const
  178. {
  179. std::string sName = cmSystemTools::LowerCase(name);
  180. return (this->Commands.find(sName) != this->Commands.end());
  181. }
  182. cmCommand *cmake::GetCommand(const char *name)
  183. {
  184. cmCommand* rm = 0;
  185. std::string sName = cmSystemTools::LowerCase(name);
  186. RegisteredCommandsMap::iterator pos = this->Commands.find(sName);
  187. if (pos != this->Commands.end())
  188. {
  189. rm = (*pos).second;
  190. }
  191. return rm;
  192. }
  193. void cmake::RenameCommand(const char*oldName, const char* newName)
  194. {
  195. // if the command already exists, free the old one
  196. std::string sOldName = cmSystemTools::LowerCase(oldName);
  197. std::string sNewName = cmSystemTools::LowerCase(newName);
  198. RegisteredCommandsMap::iterator pos = this->Commands.find(sOldName);
  199. if ( pos == this->Commands.end() )
  200. {
  201. return;
  202. }
  203. cmCommand* cmd = pos->second;
  204. pos = this->Commands.find(sNewName);
  205. if (pos != this->Commands.end())
  206. {
  207. delete pos->second;
  208. this->Commands.erase(pos);
  209. }
  210. this->Commands.insert(RegisteredCommandsMap::value_type(sNewName, cmd));
  211. pos = this->Commands.find(sOldName);
  212. this->Commands.erase(pos);
  213. }
  214. void cmake::AddCommand(cmCommand* wg)
  215. {
  216. std::string name = cmSystemTools::LowerCase(wg->GetName());
  217. // if the command already exists, free the old one
  218. RegisteredCommandsMap::iterator pos = this->Commands.find(name);
  219. if (pos != this->Commands.end())
  220. {
  221. delete pos->second;
  222. this->Commands.erase(pos);
  223. }
  224. this->Commands.insert( RegisteredCommandsMap::value_type(name, wg));
  225. }
  226. // Parse the args
  227. bool cmake::SetCacheArgs(const std::vector<std::string>& args)
  228. {
  229. for(unsigned int i=1; i < args.size(); ++i)
  230. {
  231. std::string arg = args[i];
  232. if(arg.find("-D",0) == 0)
  233. {
  234. std::string entry = arg.substr(2);
  235. if(entry.size() == 0)
  236. {
  237. entry = args[++i];
  238. }
  239. std::string var, value;
  240. cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
  241. if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type) ||
  242. cmCacheManager::ParseEntry(entry.c_str(), var, value))
  243. {
  244. this->CacheManager->AddCacheEntry(var.c_str(), value.c_str(),
  245. "No help, variable specified on the command line.",
  246. type);
  247. }
  248. else
  249. {
  250. std::cerr << "Parse error in command line argument: " << arg << "\n"
  251. << "Should be: VAR:type=value\n";
  252. cmSystemTools::Error("No cmake scrpt provided.");
  253. return false;
  254. }
  255. }
  256. else if(arg.find("-C",0) == 0)
  257. {
  258. std::string path = arg.substr(2);
  259. if ( path.size() == 0 )
  260. {
  261. path = args[++i];
  262. }
  263. std::cerr << "loading initial cache file " << path.c_str() << "\n";
  264. this->ReadListFile(path.c_str());
  265. }
  266. else if(arg.find("-P",0) == 0)
  267. {
  268. i++;
  269. std::string path = args[i];
  270. if ( path.size() == 0 )
  271. {
  272. cmSystemTools::Error("No cmake script provided.");
  273. return false;
  274. }
  275. this->ReadListFile(path.c_str());
  276. }
  277. }
  278. return true;
  279. }
  280. void cmake::ReadListFile(const char *path)
  281. {
  282. // if a generator was not yet created, temporarily create one
  283. cmGlobalGenerator *gg = this->GetGlobalGenerator();
  284. bool created = false;
  285. // if a generator was not specified use a generic one
  286. if (!gg)
  287. {
  288. gg = new cmGlobalGenerator;
  289. gg->SetCMakeInstance(this);
  290. created = true;
  291. }
  292. // read in the list file to fill the cache
  293. if(path)
  294. {
  295. std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
  296. lg->SetGlobalGenerator(gg);
  297. lg->GetMakefile()->SetHomeOutputDirectory
  298. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  299. lg->GetMakefile()->SetStartOutputDirectory
  300. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  301. lg->GetMakefile()->SetHomeDirectory
  302. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  303. lg->GetMakefile()->SetStartDirectory
  304. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  305. if (!lg->GetMakefile()->ReadListFile(0, path))
  306. {
  307. std::cerr << "Error processing file:" << path << "\n";
  308. }
  309. }
  310. // free generic one if generated
  311. if (created)
  312. {
  313. delete gg;
  314. }
  315. }
  316. // Parse the args
  317. void cmake::SetArgs(const std::vector<std::string>& args)
  318. {
  319. bool directoriesSet = false;
  320. for(unsigned int i=1; i < args.size(); ++i)
  321. {
  322. std::string arg = args[i];
  323. if(arg.find("-H",0) == 0)
  324. {
  325. directoriesSet = true;
  326. std::string path = arg.substr(2);
  327. path = cmSystemTools::CollapseFullPath(path.c_str());
  328. cmSystemTools::ConvertToUnixSlashes(path);
  329. this->SetHomeDirectory(path.c_str());
  330. }
  331. else if(arg.find("-S",0) == 0)
  332. {
  333. // There is no local generate anymore. Ignore -S option.
  334. }
  335. else if(arg.find("-O",0) == 0)
  336. {
  337. // There is no local generate anymore. Ignore -O option.
  338. }
  339. else if(arg.find("-B",0) == 0)
  340. {
  341. directoriesSet = true;
  342. std::string path = arg.substr(2);
  343. path = cmSystemTools::CollapseFullPath(path.c_str());
  344. cmSystemTools::ConvertToUnixSlashes(path);
  345. this->SetHomeOutputDirectory(path.c_str());
  346. }
  347. else if((i < args.size()-1) && (arg.find("--check-build-system",0) == 0))
  348. {
  349. this->CheckBuildSystemArgument = args[++i];
  350. this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
  351. }
  352. else if(arg.find("-V",0) == 0)
  353. {
  354. this->Verbose = true;
  355. }
  356. else if(arg.find("-D",0) == 0)
  357. {
  358. // skip for now
  359. }
  360. else if(arg.find("-C",0) == 0)
  361. {
  362. // skip for now
  363. }
  364. else if(arg.find("-P",0) == 0)
  365. {
  366. // skip for now
  367. i++;
  368. }
  369. else if(arg.find("--graphviz=",0) == 0)
  370. {
  371. std::string path = arg.substr(strlen("--graphviz="));
  372. path = cmSystemTools::CollapseFullPath(path.c_str());
  373. cmSystemTools::ConvertToUnixSlashes(path);
  374. this->GraphVizFile = path;
  375. if ( this->GraphVizFile.empty() )
  376. {
  377. cmSystemTools::Error("No file specified for --graphviz");
  378. }
  379. }
  380. else if(arg.find("--debug-trycompile",0) == 0)
  381. {
  382. std::cout << "debug trycompile on\n";
  383. this->DebugTryCompileOn();
  384. }
  385. else if(arg.find("-G",0) == 0)
  386. {
  387. std::string value = arg.substr(2);
  388. if(value.size() == 0)
  389. {
  390. value = args[++i];
  391. }
  392. cmGlobalGenerator* gen =
  393. this->CreateGlobalGenerator(value.c_str());
  394. if(!gen)
  395. {
  396. cmSystemTools::Error("Could not create named generator ",
  397. value.c_str());
  398. }
  399. else
  400. {
  401. this->SetGlobalGenerator(gen);
  402. }
  403. }
  404. // no option assume it is the path to the source
  405. else
  406. {
  407. directoriesSet = true;
  408. this->SetDirectoriesFromFile(arg.c_str());
  409. }
  410. }
  411. if(!directoriesSet)
  412. {
  413. this->SetHomeOutputDirectory
  414. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  415. this->SetStartOutputDirectory
  416. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  417. this->SetHomeDirectory
  418. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  419. this->SetStartDirectory
  420. (cmSystemTools::GetCurrentWorkingDirectory().c_str());
  421. }
  422. this->SetStartDirectory(this->GetHomeDirectory());
  423. this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
  424. }
  425. //----------------------------------------------------------------------------
  426. void cmake::SetDirectoriesFromFile(const char* arg)
  427. {
  428. // Check if the argument refers to a CMakeCache.txt or
  429. // CMakeLists.txt file.
  430. std::string listPath;
  431. std::string cachePath;
  432. bool argIsFile = false;
  433. if(cmSystemTools::FileIsDirectory(arg))
  434. {
  435. std::string path = cmSystemTools::CollapseFullPath(arg);
  436. cmSystemTools::ConvertToUnixSlashes(path);
  437. std::string cacheFile = path;
  438. cacheFile += "/CMakeCache.txt";
  439. std::string listFile = path;
  440. listFile += "/CMakeLists.txt";
  441. if(cmSystemTools::FileExists(cacheFile.c_str()))
  442. {
  443. cachePath = path;
  444. }
  445. if(cmSystemTools::FileExists(listFile.c_str()))
  446. {
  447. listPath = path;
  448. }
  449. }
  450. else if(cmSystemTools::FileExists(arg))
  451. {
  452. argIsFile = true;
  453. std::string fullPath = cmSystemTools::CollapseFullPath(arg);
  454. std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
  455. name = cmSystemTools::LowerCase(name);
  456. if(name == "cmakecache.txt")
  457. {
  458. cachePath = cmSystemTools::GetFilenamePath(fullPath.c_str());
  459. }
  460. else if(name == "cmakelists.txt")
  461. {
  462. listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
  463. }
  464. }
  465. else
  466. {
  467. // Specified file or directory does not exist. Try to set things
  468. // up to produce a meaningful error message.
  469. std::string fullPath = cmSystemTools::CollapseFullPath(arg);
  470. std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
  471. name = cmSystemTools::LowerCase(name);
  472. if(name == "cmakecache.txt" || name == "cmakelists.txt")
  473. {
  474. argIsFile = true;
  475. listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
  476. }
  477. else
  478. {
  479. listPath = fullPath;
  480. }
  481. }
  482. // If there is a CMakeCache.txt file, use its settings.
  483. if(cachePath.length() > 0)
  484. {
  485. cmCacheManager* cachem = this->GetCacheManager();
  486. cmCacheManager::CacheIterator it = cachem->NewIterator();
  487. if(cachem->LoadCache(cachePath.c_str()) &&
  488. it.Find("CMAKE_HOME_DIRECTORY"))
  489. {
  490. this->SetHomeOutputDirectory(cachePath.c_str());
  491. this->SetStartOutputDirectory(cachePath.c_str());
  492. this->SetHomeDirectory(it.GetValue());
  493. this->SetStartDirectory(it.GetValue());
  494. return;
  495. }
  496. }
  497. // If there is a CMakeLists.txt file, use it as the source tree.
  498. if(listPath.length() > 0)
  499. {
  500. this->SetHomeDirectory(listPath.c_str());
  501. this->SetStartDirectory(listPath.c_str());
  502. if(argIsFile)
  503. {
  504. // Source CMakeLists.txt file given. It was probably dropped
  505. // onto the executable in a GUI. Default to an in-source build.
  506. this->SetHomeOutputDirectory(listPath.c_str());
  507. this->SetStartOutputDirectory(listPath.c_str());
  508. }
  509. else
  510. {
  511. // Source directory given on command line. Use current working
  512. // directory as build tree.
  513. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  514. this->SetHomeOutputDirectory(cwd.c_str());
  515. this->SetStartOutputDirectory(cwd.c_str());
  516. }
  517. return;
  518. }
  519. // We didn't find a CMakeLists.txt or CMakeCache.txt file from the
  520. // argument. Assume it is the path to the source tree, and use the
  521. // current working directory as the build tree.
  522. std::string full = cmSystemTools::CollapseFullPath(arg);
  523. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  524. this->SetHomeDirectory(full.c_str());
  525. this->SetStartDirectory(full.c_str());
  526. this->SetHomeOutputDirectory(cwd.c_str());
  527. this->SetStartOutputDirectory(cwd.c_str());
  528. }
  529. // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the
  530. // cache
  531. int cmake::AddCMakePaths(const char *arg0)
  532. {
  533. // Find our own executable.
  534. std::vector<cmStdString> failures;
  535. std::string cMakeSelf = arg0;
  536. cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
  537. failures.push_back(cMakeSelf);
  538. cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str());
  539. cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
  540. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  541. {
  542. #ifdef CMAKE_BUILD_DIR
  543. std::string intdir = ".";
  544. #ifdef CMAKE_INTDIR
  545. intdir = CMAKE_INTDIR;
  546. #endif
  547. cMakeSelf = CMAKE_BUILD_DIR;
  548. cMakeSelf += "/bin/";
  549. cMakeSelf += intdir;
  550. cMakeSelf += "/cmake";
  551. cMakeSelf += cmSystemTools::GetExecutableExtension();
  552. #endif
  553. }
  554. #ifdef CMAKE_PREFIX
  555. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  556. {
  557. failures.push_back(cMakeSelf);
  558. cMakeSelf = CMAKE_PREFIX "/bin/cmake";
  559. }
  560. #endif
  561. if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
  562. {
  563. failures.push_back(cMakeSelf);
  564. cmOStringStream msg;
  565. msg << "CMAKE can not find the command line program cmake.\n";
  566. msg << " argv[0] = \"" << arg0 << "\"\n";
  567. msg << " Attempted paths:\n";
  568. std::vector<cmStdString>::iterator i;
  569. for(i=failures.begin(); i != failures.end(); ++i)
  570. {
  571. msg << " \"" << i->c_str() << "\"\n";
  572. }
  573. cmSystemTools::Error(msg.str().c_str());
  574. return 0;
  575. }
  576. // Save the value in the cache
  577. this->CacheManager->AddCacheEntry
  578. ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.",
  579. cmCacheManager::INTERNAL);
  580. // Find and save the command to edit the cache
  581. std::string editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  582. "/ccmake" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  583. if( !cmSystemTools::FileExists(editCacheCommand.c_str()))
  584. {
  585. editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  586. "/CMakeSetup" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  587. }
  588. std::string ctestCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
  589. "/ctest" + cmSystemTools::GetFilenameExtension(cMakeSelf);
  590. if(cmSystemTools::FileExists(ctestCommand.c_str()))
  591. {
  592. this->CacheManager->AddCacheEntry
  593. ("CMAKE_CTEST_COMMAND", ctestCommand.c_str(),
  594. "Path to ctest program executable.", cmCacheManager::INTERNAL);
  595. }
  596. if(cmSystemTools::FileExists(editCacheCommand.c_str()))
  597. {
  598. this->CacheManager->AddCacheEntry
  599. ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
  600. "Path to cache edit program executable.", cmCacheManager::INTERNAL);
  601. }
  602. // do CMAKE_ROOT, look for the environment variable first
  603. std::string cMakeRoot;
  604. std::string modules;
  605. if (getenv("CMAKE_ROOT"))
  606. {
  607. cMakeRoot = getenv("CMAKE_ROOT");
  608. modules = cMakeRoot + "/Modules/CMake.cmake";
  609. }
  610. if(!cmSystemTools::FileExists(modules.c_str()))
  611. {
  612. // next try exe/..
  613. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  614. std::string::size_type slashPos = cMakeRoot.rfind("/");
  615. if(slashPos != std::string::npos)
  616. {
  617. cMakeRoot = cMakeRoot.substr(0, slashPos);
  618. }
  619. // is there no Modules direcory there?
  620. modules = cMakeRoot + "/Modules/CMake.cmake";
  621. }
  622. if (!cmSystemTools::FileExists(modules.c_str()))
  623. {
  624. // try exe/../share/cmake
  625. cMakeRoot += CMAKE_DATA_DIR;
  626. modules = cMakeRoot + "/Modules/CMake.cmake";
  627. }
  628. #ifdef CMAKE_ROOT_DIR
  629. if (!cmSystemTools::FileExists(modules.c_str()))
  630. {
  631. // try compiled in root directory
  632. cMakeRoot = CMAKE_ROOT_DIR;
  633. modules = cMakeRoot + "/Modules/CMake.cmake";
  634. }
  635. #endif
  636. #ifdef CMAKE_PREFIX
  637. if (!cmSystemTools::FileExists(modules.c_str()))
  638. {
  639. // try compiled in install prefix
  640. cMakeRoot = CMAKE_PREFIX CMAKE_DATA_DIR;
  641. modules = cMakeRoot + "/Modules/CMake.cmake";
  642. }
  643. #endif
  644. if (!cmSystemTools::FileExists(modules.c_str()))
  645. {
  646. // try
  647. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  648. cMakeRoot += CMAKE_DATA_DIR;
  649. modules = cMakeRoot + "/Modules/CMake.cmake";
  650. }
  651. if(!cmSystemTools::FileExists(modules.c_str()))
  652. {
  653. // next try exe
  654. cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
  655. // is there no Modules direcory there?
  656. modules = cMakeRoot + "/Modules/CMake.cmake";
  657. }
  658. if (!cmSystemTools::FileExists(modules.c_str()))
  659. {
  660. // couldn't find modules
  661. cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n"
  662. "CMake has most likely not been installed correctly.\n"
  663. "Modules directory not found in\n",
  664. cMakeRoot.c_str());
  665. return 0;
  666. }
  667. this->CacheManager->AddCacheEntry
  668. ("CMAKE_ROOT", cMakeRoot.c_str(),
  669. "Path to CMake installation.", cmCacheManager::INTERNAL);
  670. #ifdef _WIN32
  671. std::string comspec = "cmw9xcom.exe";
  672. cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
  673. #endif
  674. return 1;
  675. }
  676. void CMakeCommandUsage(const char* program)
  677. {
  678. cmOStringStream errorStream;
  679. #ifdef CMAKE_BUILD_WITH_CMAKE
  680. errorStream
  681. << "cmake version " << cmVersion::GetCMakeVersion() << "\n";
  682. #else
  683. errorStream
  684. << "cmake bootstrap\n";
  685. #endif
  686. errorStream
  687. << "Usage: " << program << " -E [command] [arguments ...]\n"
  688. << "Available commands: \n"
  689. << " chdir dir cmd [args]... - run command in a given directory\n"
  690. << " copy file destination - copy file to destination (either file or "
  691. "directory)\n"
  692. << " copy_if_different in-file out-file - copy file if input has "
  693. "changed\n"
  694. << " copy_directory source destination - copy directory 'source' "
  695. "content to directory 'destination'\n"
  696. << " compare_files file1 file2 - check if file1 is same as file2\n"
  697. << " echo [string]... - displays arguments as text\n"
  698. << " environment - display the current enviroment\n"
  699. << " remove file1 file2 ... - remove the file(s)\n"
  700. << " tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar.\n"
  701. << " time command [args] ... - run command and return elapsed time\n"
  702. #if defined(_WIN32) && !defined(__CYGWIN__)
  703. << " write_regv key value - write registry value\n"
  704. << " delete_regv key - delete registry value\n"
  705. << " comspec - on windows 9x use this for RunCommand\n"
  706. #else
  707. << " create_symlink old new - create a symbolic link new -> old\n"
  708. #endif
  709. ;
  710. cmSystemTools::Error(errorStream.str().c_str());
  711. }
  712. int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
  713. {
  714. if (args.size() > 1)
  715. {
  716. // Copy file
  717. if (args[1] == "copy" && args.size() == 4)
  718. {
  719. if(!cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str()))
  720. {
  721. std::cerr << "Error copying file \"" << args[2].c_str()
  722. << "\" to \"" << args[3].c_str() << "\".\n";
  723. return 1;
  724. }
  725. return 0;
  726. }
  727. // Copy file if different.
  728. if (args[1] == "copy_if_different" && args.size() == 4)
  729. {
  730. if(!cmSystemTools::CopyFileIfDifferent(args[2].c_str(),
  731. args[3].c_str()))
  732. {
  733. std::cerr << "Error copying file (if different) from \""
  734. << args[2].c_str() << "\" to \"" << args[3].c_str()
  735. << "\".\n";
  736. return 1;
  737. }
  738. return 0;
  739. }
  740. // Copy directory content
  741. if (args[1] == "copy_directory" && args.size() == 4)
  742. {
  743. if(!cmSystemTools::CopyADirectory(args[2].c_str(), args[3].c_str()))
  744. {
  745. std::cerr << "Error copying directory from \""
  746. << args[2].c_str() << "\" to \"" << args[3].c_str()
  747. << "\".\n";
  748. return 1;
  749. }
  750. return 0;
  751. }
  752. // Compare files
  753. if (args[1] == "compare_files" && args.size() == 4)
  754. {
  755. if(cmSystemTools::FilesDiffer(args[2].c_str(), args[3].c_str()))
  756. {
  757. std::cerr << "Files \""
  758. << args[2].c_str() << "\" to \"" << args[3].c_str()
  759. << "\" are different.\n";
  760. return 1;
  761. }
  762. return 0;
  763. }
  764. // Echo string
  765. else if (args[1] == "echo" )
  766. {
  767. unsigned int cc;
  768. const char* space = "";
  769. for ( cc = 2; cc < args.size(); cc ++ )
  770. {
  771. std::cout << space << args[cc];
  772. space = " ";
  773. }
  774. std::cout << std::endl;
  775. return 0;
  776. }
  777. // Command to create a symbolic link. Fails on platforms not
  778. // supporting them.
  779. else if (args[1] == "environment" )
  780. {
  781. std::vector<std::string> env = cmSystemTools::GetEnvironmentVariables();
  782. std::vector<std::string>::iterator it;
  783. for ( it = env.begin(); it != env.end(); ++ it )
  784. {
  785. std::cout << it->c_str() << std::endl;
  786. }
  787. return 0;
  788. }
  789. // Remove file
  790. else if (args[1] == "remove" && args.size() > 2)
  791. {
  792. for (std::string::size_type cc = 2; cc < args.size(); cc ++)
  793. {
  794. if(args[cc] != "-f")
  795. {
  796. if(args[cc] == "\\-f")
  797. {
  798. args[cc] = "-f";
  799. }
  800. cmSystemTools::RemoveFile(args[cc].c_str());
  801. }
  802. }
  803. return 0;
  804. }
  805. // Clock command
  806. else if (args[1] == "time" && args.size() > 2)
  807. {
  808. std::string command = args[2];
  809. for (std::string::size_type cc = 3; cc < args.size(); cc ++)
  810. {
  811. command += " ";
  812. command += args[cc];
  813. }
  814. clock_t clock_start, clock_finish;
  815. time_t time_start, time_finish;
  816. time(&time_start);
  817. clock_start = clock();
  818. cmSystemTools::RunSingleCommand(command.c_str());
  819. clock_finish = clock();
  820. time(&time_finish);
  821. double clocks_per_sec = (double)CLOCKS_PER_SEC;
  822. std::cout << "Elapsed time: "
  823. << (long)(time_finish - time_start) << " s. (time)"
  824. << ", "
  825. << (double)(clock_finish - clock_start) / clocks_per_sec
  826. << " s. (clock)"
  827. << "\n";
  828. return 0;
  829. }
  830. // Command to change directory and run a program.
  831. else if (args[1] == "chdir" && args.size() >= 4)
  832. {
  833. std::string directory = args[2];
  834. if(!cmSystemTools::FileExists(directory.c_str()))
  835. {
  836. cmSystemTools::Error("Directory does not exist for chdir command: ",
  837. args[2].c_str());
  838. return 0;
  839. }
  840. std::string command = "\"";
  841. command += args[3];
  842. command += "\"";
  843. for (std::string::size_type cc = 4; cc < args.size(); cc ++)
  844. {
  845. command += " \"";
  846. command += args[cc];
  847. command += "\"";
  848. }
  849. int retval = 0;
  850. int timeout = 0;
  851. if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval,
  852. directory.c_str(), true, timeout) )
  853. {
  854. return retval;
  855. }
  856. return 1;
  857. }
  858. // Command to create a symbolic link. Fails on platforms not
  859. // supporting them.
  860. else if (args[1] == "create_symlink" && args.size() == 4)
  861. {
  862. return cmSystemTools::CreateSymlink(args[2].c_str(),
  863. args[3].c_str())? 0:1;
  864. }
  865. // Internal CMake shared library support.
  866. else if (args[1] == "cmake_symlink_library" && args.size() == 5)
  867. {
  868. int result = 0;
  869. std::string realName = args[2];
  870. std::string soName = args[3];
  871. std::string name = args[4];
  872. if(soName != realName)
  873. {
  874. std::string fname = cmSystemTools::GetFilenameName(realName);
  875. if(cmSystemTools::FileExists(soName.c_str()))
  876. {
  877. cmSystemTools::RemoveFile(soName.c_str());
  878. }
  879. if(!cmSystemTools::CreateSymlink(fname.c_str(), soName.c_str()))
  880. {
  881. result = 1;
  882. }
  883. }
  884. if(name != soName)
  885. {
  886. std::string fname = cmSystemTools::GetFilenameName(soName);
  887. if(cmSystemTools::FileExists(soName.c_str()))
  888. {
  889. cmSystemTools::RemoveFile(name.c_str());
  890. }
  891. if(!cmSystemTools::CreateSymlink(fname.c_str(), name.c_str()))
  892. {
  893. result = 1;
  894. }
  895. }
  896. return result;
  897. }
  898. // Internal CMake versioned executable support.
  899. else if (args[1] == "cmake_symlink_executable" && args.size() == 4)
  900. {
  901. int result = 0;
  902. std::string realName = args[2];
  903. std::string name = args[3];
  904. if(name != realName)
  905. {
  906. std::string fname = cmSystemTools::GetFilenameName(realName);
  907. if(cmSystemTools::FileExists(realName.c_str()))
  908. {
  909. cmSystemTools::RemoveFile(name.c_str());
  910. }
  911. if(!cmSystemTools::CreateSymlink(fname.c_str(), name.c_str()))
  912. {
  913. result = 1;
  914. }
  915. }
  916. return result;
  917. }
  918. // Internal CMake dependency scanning support.
  919. else if (args[1] == "cmake_depends" && args.size() >= 6)
  920. {
  921. cmake cm;
  922. cmGlobalGenerator *ggd = cm.CreateGlobalGenerator(args[2].c_str());
  923. if (ggd)
  924. {
  925. ggd->SetCMakeInstance(&cm);
  926. std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
  927. lgd->SetGlobalGenerator(ggd);
  928. return lgd->ScanDependencies(args)? 0 : 2;
  929. }
  930. return 1;
  931. }
  932. // Tar files
  933. else if (args[1] == "tar" && args.size() > 3)
  934. {
  935. std::string flags = args[2];
  936. std::string outFile = args[3];
  937. std::vector<cmStdString> files;
  938. for (std::string::size_type cc = 4; cc < args.size(); cc ++)
  939. {
  940. files.push_back(args[cc]);
  941. }
  942. bool gzip = false;
  943. bool verbose = false;
  944. if ( flags.find_first_of('z') != flags.npos )
  945. {
  946. gzip = true;
  947. }
  948. if ( flags.find_first_of('v') != flags.npos )
  949. {
  950. verbose = true;
  951. }
  952. if ( flags.find_first_of('t') != flags.npos )
  953. {
  954. if ( !cmSystemTools::ListTar(outFile.c_str(), files, gzip, verbose) )
  955. {
  956. cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
  957. return 1;
  958. }
  959. }
  960. else if ( flags.find_first_of('c') != flags.npos )
  961. {
  962. if ( !cmSystemTools::CreateTar(
  963. outFile.c_str(), files, gzip, verbose) )
  964. {
  965. cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
  966. return 1;
  967. }
  968. }
  969. else if ( flags.find_first_of('x') != flags.npos )
  970. {
  971. if ( !cmSystemTools::ExtractTar(
  972. outFile.c_str(), files, gzip, verbose) )
  973. {
  974. cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
  975. return 1;
  976. }
  977. }
  978. return 0;
  979. }
  980. #if defined(CMAKE_BUILD_WITH_CMAKE)
  981. // Internal CMake Fortran module support.
  982. else if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4)
  983. {
  984. return cmDependsFortran::CopyModule(args)? 0 : 1;
  985. }
  986. #endif
  987. #if defined(_WIN32) && !defined(__CYGWIN__)
  988. // Write registry value
  989. else if (args[1] == "write_regv" && args.size() > 3)
  990. {
  991. return cmSystemTools::WriteRegistryValue(args[2].c_str(),
  992. args[3].c_str()) ? 0 : 1;
  993. }
  994. // Delete registry value
  995. else if (args[1] == "delete_regv" && args.size() > 2)
  996. {
  997. return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
  998. }
  999. // Remove file
  1000. else if (args[1] == "comspec" && args.size() > 2)
  1001. {
  1002. unsigned int cc;
  1003. std::string command = args[2];
  1004. for ( cc = 3; cc < args.size(); cc ++ )
  1005. {
  1006. command += " " + args[cc];
  1007. }
  1008. return cmWin32ProcessExecution::Windows9xHack(command.c_str());
  1009. }
  1010. #endif
  1011. }
  1012. ::CMakeCommandUsage(args[0].c_str());
  1013. return 1;
  1014. }
  1015. void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
  1016. {
  1017. for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
  1018. i != this->Generators.end(); ++i)
  1019. {
  1020. names.push_back(i->first);
  1021. }
  1022. }
  1023. cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
  1024. {
  1025. RegisteredGeneratorsMap::const_iterator i = this->Generators.find(name);
  1026. if(i != this->Generators.end())
  1027. {
  1028. cmGlobalGenerator* generator = (i->second)();
  1029. generator->SetCMakeInstance(this);
  1030. return generator;
  1031. }
  1032. else
  1033. {
  1034. return 0;
  1035. }
  1036. }
  1037. void cmake::SetHomeDirectory(const char* dir)
  1038. {
  1039. this->cmHomeDirectory = dir;
  1040. cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
  1041. }
  1042. void cmake::SetHomeOutputDirectory(const char* lib)
  1043. {
  1044. this->HomeOutputDirectory = lib;
  1045. cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
  1046. }
  1047. void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
  1048. {
  1049. // delete the old generator
  1050. if (this->GlobalGenerator)
  1051. {
  1052. delete this->GlobalGenerator;
  1053. // restore the original environment variables CXX and CC
  1054. // Restor CC
  1055. std::string env = "CC=";
  1056. if(this->CCEnvironment.size())
  1057. {
  1058. env += this->CCEnvironment;
  1059. }
  1060. cmSystemTools::PutEnv(env.c_str());
  1061. env = "CXX=";
  1062. if(this->CXXEnvironment.size())
  1063. {
  1064. env += this->CXXEnvironment;
  1065. }
  1066. cmSystemTools::PutEnv(env.c_str());
  1067. }
  1068. // set the new
  1069. this->GlobalGenerator = gg;
  1070. // set the global flag for unix style paths on cmSystemTools as
  1071. // soon as the generator is set. This allows gmake to be used
  1072. // on windows.
  1073. cmSystemTools::SetForceUnixPaths(this->GlobalGenerator->GetForceUnixPaths());
  1074. // Save the environment variables CXX and CC
  1075. const char* cxx = getenv("CXX");
  1076. const char* cc = getenv("CC");
  1077. if(cxx)
  1078. {
  1079. this->CXXEnvironment = cxx;
  1080. }
  1081. else
  1082. {
  1083. this->CXXEnvironment = "";
  1084. }
  1085. if(cc)
  1086. {
  1087. this->CCEnvironment = cc;
  1088. }
  1089. else
  1090. {
  1091. this->CCEnvironment = "";
  1092. }
  1093. // set the cmake instance just to be sure
  1094. gg->SetCMakeInstance(this);
  1095. }
  1096. int cmake::DoPreConfigureChecks()
  1097. {
  1098. // Make sure the Start directory contains a CMakeLists.txt file.
  1099. std::string srcList = this->GetHomeDirectory();
  1100. srcList += "/CMakeLists.txt";
  1101. if(!cmSystemTools::FileExists(srcList.c_str()))
  1102. {
  1103. cmOStringStream err;
  1104. if(cmSystemTools::FileIsDirectory(this->GetHomeDirectory()))
  1105. {
  1106. err << "The source directory \"" << this->GetHomeDirectory()
  1107. << "\" does not appear to contain CMakeLists.txt.\n";
  1108. }
  1109. else if(cmSystemTools::FileExists(this->GetHomeDirectory()))
  1110. {
  1111. err << "The source directory \"" << this->GetHomeDirectory()
  1112. << "\" is a file, not a directory.\n";
  1113. }
  1114. else
  1115. {
  1116. err << "The source directory \"" << this->GetHomeDirectory()
  1117. << "\" does not exist.\n";
  1118. }
  1119. err << "Specify --help for usage, or press the help button on the CMake "
  1120. "GUI.";
  1121. cmSystemTools::Error(err.str().c_str());
  1122. return -2;
  1123. }
  1124. // do a sanity check on some values
  1125. if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
  1126. {
  1127. std::string cacheStart =
  1128. this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
  1129. cacheStart += "/CMakeLists.txt";
  1130. std::string currentStart = this->GetHomeDirectory();
  1131. currentStart += "/CMakeLists.txt";
  1132. if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
  1133. {
  1134. std::string message = "The source \"";
  1135. message += currentStart;
  1136. message += "\" does not match the source \"";
  1137. message += cacheStart;
  1138. message += "\" used to generate cache. ";
  1139. message += "Re-run cmake with a different source directory.";
  1140. cmSystemTools::Error(message.c_str());
  1141. return -2;
  1142. }
  1143. }
  1144. else
  1145. {
  1146. return 0;
  1147. }
  1148. return 1;
  1149. }
  1150. int cmake::Configure()
  1151. {
  1152. // Construct right now our path conversion table before it's too late:
  1153. this->UpdateConversionPathTable();
  1154. this->CleanupCommandsAndMacros();
  1155. int res = 0;
  1156. if ( !this->ScriptMode )
  1157. {
  1158. res = this->DoPreConfigureChecks();
  1159. }
  1160. if ( res < 0 )
  1161. {
  1162. return -2;
  1163. }
  1164. if ( !res )
  1165. {
  1166. this->CacheManager->AddCacheEntry
  1167. ("CMAKE_HOME_DIRECTORY",
  1168. this->GetHomeDirectory(),
  1169. "Start directory with the top level CMakeLists.txt file for this "
  1170. "project",
  1171. cmCacheManager::INTERNAL);
  1172. }
  1173. // set the default BACKWARDS compatibility to the current version
  1174. if(!this->CacheManager->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
  1175. {
  1176. char ver[256];
  1177. sprintf(ver,"%i.%i",cmMakefile::GetMajorVersion(),
  1178. cmMakefile::GetMinorVersion());
  1179. this->CacheManager->AddCacheEntry
  1180. ("CMAKE_BACKWARDS_COMPATIBILITY",ver,
  1181. "For backwards compatibility, what version of CMake commands and "
  1182. "syntax should this version of CMake allow.",
  1183. cmCacheManager::STRING);
  1184. }
  1185. // no generator specified on the command line
  1186. if(!this->GlobalGenerator)
  1187. {
  1188. const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
  1189. if(genName)
  1190. {
  1191. this->GlobalGenerator = this->CreateGlobalGenerator(genName);
  1192. }
  1193. if(this->GlobalGenerator)
  1194. {
  1195. // set the global flag for unix style paths on cmSystemTools as
  1196. // soon as the generator is set. This allows gmake to be used
  1197. // on windows.
  1198. cmSystemTools::SetForceUnixPaths
  1199. (this->GlobalGenerator->GetForceUnixPaths());
  1200. }
  1201. else
  1202. {
  1203. #if defined(__BORLANDC__) && defined(_WIN32)
  1204. this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
  1205. #elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
  1206. std::string installedCompiler;
  1207. std::string mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft"
  1208. "\\VisualStudio\\8.0\\Setup;Dbghelp_path]";
  1209. cmSystemTools::ExpandRegistryValues(mp);
  1210. if (!(mp == "/registry"))
  1211. {
  1212. installedCompiler = "Visual Studio 8 2005";
  1213. }
  1214. else
  1215. {
  1216. mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft"
  1217. "\\VisualStudio\\7.1;InstallDir]";
  1218. cmSystemTools::ExpandRegistryValues(mp);
  1219. if (!(mp == "/registry"))
  1220. {
  1221. installedCompiler = "Visual Studio 7 .NET 2003";
  1222. }
  1223. else
  1224. {
  1225. mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft"
  1226. "\\VisualStudio\\7.0;InstallDir]";
  1227. cmSystemTools::ExpandRegistryValues(mp);
  1228. if (!(mp == "/registry"))
  1229. {
  1230. installedCompiler = "Visual Studio 7";
  1231. }
  1232. else
  1233. {
  1234. installedCompiler = "Visual Studio 6";
  1235. }
  1236. }
  1237. }
  1238. cmGlobalGenerator* gen
  1239. = this->CreateGlobalGenerator(installedCompiler.c_str());
  1240. if(!gen)
  1241. {
  1242. gen = new cmGlobalNMakeMakefileGenerator;
  1243. }
  1244. this->SetGlobalGenerator(gen);
  1245. #else
  1246. this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3);
  1247. #endif
  1248. }
  1249. if(!this->GlobalGenerator)
  1250. {
  1251. cmSystemTools::Error("Could not create generator");
  1252. return -1;
  1253. }
  1254. }
  1255. const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
  1256. if(genName)
  1257. {
  1258. if(strcmp(this->GlobalGenerator->GetName(), genName) != 0)
  1259. {
  1260. std::string message = "Error: generator : ";
  1261. message += this->GlobalGenerator->GetName();
  1262. message += "\nDoes not match the generator used previously: ";
  1263. message += genName;
  1264. message +=
  1265. "\nEither remove the CMakeCache.txt file or choose a different"
  1266. " binary directory.";
  1267. cmSystemTools::Error(message.c_str());
  1268. return -2;
  1269. }
  1270. }
  1271. if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR"))
  1272. {
  1273. this->CacheManager->AddCacheEntry("CMAKE_GENERATOR",
  1274. this->GlobalGenerator->GetName(),
  1275. "Name of generator.",
  1276. cmCacheManager::INTERNAL);
  1277. }
  1278. // reset any system configuration information, except for when we are
  1279. // InTryCompile. With TryCompile the system info is taken from the parent's
  1280. // info to save time
  1281. if (!this->InTryCompile)
  1282. {
  1283. this->GlobalGenerator->ClearEnabledLanguages();
  1284. }
  1285. this->CleanupWrittenFiles();
  1286. // Truncate log files
  1287. if (!this->InTryCompile)
  1288. {
  1289. this->TruncateOutputLog("CMakeOutput.log");
  1290. this->TruncateOutputLog("CMakeError.log");
  1291. }
  1292. // actually do the configure
  1293. this->GlobalGenerator->Configure();
  1294. // Before saving the cache
  1295. // if the project did not define one of the entries below, add them now
  1296. // so users can edit the values in the cache:
  1297. // LIBRARY_OUTPUT_PATH
  1298. // EXECUTABLE_OUTPUT_PATH
  1299. if(!this->CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH"))
  1300. {
  1301. this->CacheManager->AddCacheEntry
  1302. ("LIBRARY_OUTPUT_PATH", "",
  1303. "Single output directory for building all libraries.",
  1304. cmCacheManager::PATH);
  1305. }
  1306. if(!this->CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
  1307. {
  1308. this->CacheManager->AddCacheEntry
  1309. ("EXECUTABLE_OUTPUT_PATH", "",
  1310. "Single output directory for building all executables.",
  1311. cmCacheManager::PATH);
  1312. }
  1313. if(!this->CacheManager->GetCacheValue("CMAKE_USE_RELATIVE_PATHS"))
  1314. {
  1315. this->CacheManager->AddCacheEntry
  1316. ("CMAKE_USE_RELATIVE_PATHS", false,
  1317. "If true, cmake will use relative paths in makefiles and projects.");
  1318. cmCacheManager::CacheIterator it =
  1319. this->CacheManager->GetCacheIterator("CMAKE_USE_RELATIVE_PATHS");
  1320. if ( !it.PropertyExists("ADVANCED") )
  1321. {
  1322. it.SetProperty("ADVANCED", "1");
  1323. }
  1324. }
  1325. if(cmSystemTools::GetFatalErrorOccured() &&
  1326. (!this->CacheManager->GetCacheValue("CMAKE_MAKE_PROGRAM") ||
  1327. cmSystemTools::IsOff(this->CacheManager->
  1328. GetCacheValue("CMAKE_MAKE_PROGRAM"))))
  1329. {
  1330. // We must have a bad generator selection. Wipe the cache entry so the
  1331. // user can select another.
  1332. this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR");
  1333. }
  1334. // only save the cache if there were no fatal errors
  1335. if ( !this->ScriptMode && !cmSystemTools::GetFatalErrorOccured() )
  1336. {
  1337. this->CacheManager->SaveCache(this->GetHomeOutputDirectory());
  1338. }
  1339. if ( !this->GraphVizFile.empty() )
  1340. {
  1341. std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
  1342. this->GenerateGraphViz(this->GraphVizFile.c_str());
  1343. }
  1344. if(cmSystemTools::GetErrorOccuredFlag())
  1345. {
  1346. return -1;
  1347. }
  1348. return 0;
  1349. }
  1350. bool cmake::CacheVersionMatches()
  1351. {
  1352. const char* majv =
  1353. this->CacheManager->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION");
  1354. const char* minv =
  1355. this->CacheManager->GetCacheValue("CMAKE_CACHE_MINOR_VERSION");
  1356. const char* relv =
  1357. this->CacheManager->GetCacheValue("CMAKE_CACHE_RELEASE_VERSION");
  1358. bool cacheSameCMake = false;
  1359. if(majv &&
  1360. atoi(majv) == static_cast<int>(cmMakefile::GetMajorVersion())
  1361. && minv &&
  1362. atoi(minv) == static_cast<int>(cmMakefile::GetMinorVersion())
  1363. && relv && (strcmp(relv, cmMakefile::GetReleaseVersion()) == 0))
  1364. {
  1365. cacheSameCMake = true;
  1366. }
  1367. return cacheSameCMake;
  1368. }
  1369. void cmake::PreLoadCMakeFiles()
  1370. {
  1371. std::string pre_load = this->GetHomeDirectory();
  1372. if ( pre_load.size() > 0 )
  1373. {
  1374. pre_load += "/PreLoad.cmake";
  1375. if ( cmSystemTools::FileExists(pre_load.c_str()) )
  1376. {
  1377. this->ReadListFile(pre_load.c_str());
  1378. }
  1379. }
  1380. pre_load = this->GetHomeOutputDirectory();
  1381. if ( pre_load.size() > 0 )
  1382. {
  1383. pre_load += "/PreLoad.cmake";
  1384. if ( cmSystemTools::FileExists(pre_load.c_str()) )
  1385. {
  1386. this->ReadListFile(pre_load.c_str());
  1387. }
  1388. }
  1389. }
  1390. // handle a command line invocation
  1391. int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
  1392. {
  1393. // Process the arguments
  1394. this->SetArgs(args);
  1395. if(cmSystemTools::GetErrorOccuredFlag())
  1396. {
  1397. CMakeCommandUsage(args[0].c_str());
  1398. return -1;
  1399. }
  1400. // set the cmake command
  1401. this->CMakeCommand = args[0];
  1402. if ( !this->ScriptMode )
  1403. {
  1404. // load the cache
  1405. if(this->LoadCache() < 0)
  1406. {
  1407. cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n");
  1408. return -1;
  1409. }
  1410. }
  1411. else
  1412. {
  1413. this->AddCMakePaths(this->CMakeCommand.c_str());
  1414. }
  1415. // Add any cache args
  1416. if ( !this->SetCacheArgs(args) )
  1417. {
  1418. cmSystemTools::Error("Problem processing arguments. Aborting.\n");
  1419. return -1;
  1420. }
  1421. // In script mode we terminate after running the script.
  1422. if(this->ScriptMode)
  1423. {
  1424. if(cmSystemTools::GetErrorOccuredFlag())
  1425. {
  1426. return -1;
  1427. }
  1428. else
  1429. {
  1430. return 0;
  1431. }
  1432. }
  1433. this->PreLoadCMakeFiles();
  1434. std::string systemFile = this->GetHomeOutputDirectory();
  1435. systemFile += "/CMakeSystem.cmake";
  1436. if ( noconfigure )
  1437. {
  1438. return 0;
  1439. }
  1440. // now run the global generate
  1441. // Check the state of the build system to see if we need to regenerate.
  1442. if(!this->CheckBuildSystem())
  1443. {
  1444. return 0;
  1445. }
  1446. // If we are doing global generate, we better set start and start
  1447. // output directory to the root of the project.
  1448. std::string oldstartdir = this->GetStartDirectory();
  1449. std::string oldstartoutputdir = this->GetStartOutputDirectory();
  1450. this->SetStartDirectory(this->GetHomeDirectory());
  1451. this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
  1452. int ret = this->Configure();
  1453. if (ret || this->ScriptMode)
  1454. {
  1455. return ret;
  1456. }
  1457. ret = this->Generate();
  1458. std::string message = "Build files have been written to: ";
  1459. message += this->GetHomeOutputDirectory();
  1460. this->UpdateProgress(message.c_str(), -1);
  1461. if(ret)
  1462. {
  1463. return ret;
  1464. }
  1465. this->SetStartDirectory(oldstartdir.c_str());
  1466. this->SetStartOutputDirectory(oldstartoutputdir.c_str());
  1467. return ret;
  1468. }
  1469. int cmake::Generate()
  1470. {
  1471. if(!this->GlobalGenerator)
  1472. {
  1473. return -1;
  1474. }
  1475. this->GlobalGenerator->Generate();
  1476. if(cmSystemTools::GetErrorOccuredFlag())
  1477. {
  1478. return -1;
  1479. }
  1480. return 0;
  1481. }
  1482. unsigned int cmake::GetMajorVersion()
  1483. {
  1484. return cmMakefile::GetMajorVersion();
  1485. }
  1486. unsigned int cmake::GetMinorVersion()
  1487. {
  1488. return cmMakefile::GetMinorVersion();
  1489. }
  1490. const char *cmake::GetReleaseVersion()
  1491. {
  1492. return cmMakefile::GetReleaseVersion();
  1493. }
  1494. void cmake::AddCacheEntry(const char* key, const char* value,
  1495. const char* helpString,
  1496. int type)
  1497. {
  1498. this->CacheManager->AddCacheEntry(key, value,
  1499. helpString,
  1500. cmCacheManager::CacheEntryType(type));
  1501. }
  1502. const char* cmake::GetCacheDefinition(const char* name) const
  1503. {
  1504. return this->CacheManager->GetCacheValue(name);
  1505. }
  1506. int cmake::DumpDocumentationToFile(std::ostream& f)
  1507. {
  1508. #ifdef CMAKE_BUILD_WITH_CMAKE
  1509. // Loop over all registered commands and print out documentation
  1510. const char *name;
  1511. const char *terse;
  1512. const char *full;
  1513. char tmp[1024];
  1514. sprintf(tmp,"Version %d.%d (%s)", cmake::GetMajorVersion(),
  1515. cmake::GetMinorVersion(), cmVersion::GetReleaseVersion().c_str());
  1516. f << "<html>\n";
  1517. f << "<h1>Documentation for commands of CMake " << tmp << "</h1>\n";
  1518. f << "<ul>\n";
  1519. for(RegisteredCommandsMap::iterator j = this->Commands.begin();
  1520. j != this->Commands.end(); ++j)
  1521. {
  1522. name = (*j).second->GetName();
  1523. terse = (*j).second->GetTerseDocumentation();
  1524. full = (*j).second->GetFullDocumentation();
  1525. f << "<li><b>" << name << "</b> - " << terse << std::endl
  1526. << "<br><i>Usage:</i> " << full << "</li>" << std::endl << std::endl;
  1527. }
  1528. f << "</ul></html>\n";
  1529. #else
  1530. (void)f;
  1531. #endif
  1532. return 1;
  1533. }
  1534. void cmake::AddDefaultCommands()
  1535. {
  1536. std::list<cmCommand*> commands;
  1537. GetBootstrapCommands(commands);
  1538. GetPredefinedCommands(commands);
  1539. for(std::list<cmCommand*>::iterator i = commands.begin();
  1540. i != commands.end(); ++i)
  1541. {
  1542. this->AddCommand(*i);
  1543. }
  1544. }
  1545. void cmake::AddDefaultGenerators()
  1546. {
  1547. #if defined(_WIN32) && !defined(__CYGWIN__)
  1548. # if !defined(CMAKE_BOOT_MINGW)
  1549. this->Generators[cmGlobalVisualStudio6Generator::GetActualName()] =
  1550. &cmGlobalVisualStudio6Generator::New;
  1551. this->Generators[cmGlobalVisualStudio7Generator::GetActualName()] =
  1552. &cmGlobalVisualStudio7Generator::New;
  1553. this->Generators[cmGlobalVisualStudio71Generator::GetActualName()] =
  1554. &cmGlobalVisualStudio71Generator::New;
  1555. this->Generators[cmGlobalVisualStudio8Generator::GetActualName()] =
  1556. &cmGlobalVisualStudio8Generator::New;
  1557. this->Generators[cmGlobalBorlandMakefileGenerator::GetActualName()] =
  1558. &cmGlobalBorlandMakefileGenerator::New;
  1559. this->Generators[cmGlobalNMakeMakefileGenerator::GetActualName()] =
  1560. &cmGlobalNMakeMakefileGenerator::New;
  1561. this->Generators[cmGlobalWatcomWMakeGenerator::GetActualName()] =
  1562. &cmGlobalWatcomWMakeGenerator::New;
  1563. # endif
  1564. this->Generators[cmGlobalMSYSMakefileGenerator::GetActualName()] =
  1565. &cmGlobalMSYSMakefileGenerator::New;
  1566. this->Generators[cmGlobalMinGWMakefileGenerator::GetActualName()] =
  1567. &cmGlobalMinGWMakefileGenerator::New;
  1568. #endif
  1569. this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] =
  1570. &cmGlobalUnixMakefileGenerator3::New;
  1571. #ifdef CMAKE_USE_XCODE
  1572. this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
  1573. &cmGlobalXCodeGenerator::New;
  1574. #endif
  1575. #ifdef CMAKE_USE_KDEVELOP
  1576. this->Generators[cmGlobalKdevelopGenerator::GetActualName()] =
  1577. &cmGlobalKdevelopGenerator::New;
  1578. #endif
  1579. }
  1580. int cmake::LoadCache()
  1581. {
  1582. // could we not read the cache
  1583. if (!this->CacheManager->LoadCache(this->GetHomeOutputDirectory()))
  1584. {
  1585. // if it does exist, but isn;t readable then warn the user
  1586. std::string cacheFile = this->GetHomeOutputDirectory();
  1587. cacheFile += "/CMakeCache.txt";
  1588. if(cmSystemTools::FileExists(cacheFile.c_str()))
  1589. {
  1590. cmSystemTools::Error(
  1591. "There is a CMakeCache.txt file for the current binary tree but "
  1592. "cmake does not have permission to read it. Please check the "
  1593. "permissions of the directory you are trying to run CMake on.");
  1594. return -1;
  1595. }
  1596. }
  1597. if (this->CMakeCommand.size() < 2)
  1598. {
  1599. cmSystemTools::Error(
  1600. "cmake command was not specified prior to loading the cache in "
  1601. "cmake.cxx");
  1602. return -1;
  1603. }
  1604. // setup CMAKE_ROOT and CMAKE_COMMAND
  1605. if(!this->AddCMakePaths(this->CMakeCommand.c_str()))
  1606. {
  1607. return -3;
  1608. }
  1609. // set the default BACKWARDS compatibility to the current version
  1610. if(!this->CacheManager->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
  1611. {
  1612. char ver[256];
  1613. sprintf(ver,"%i.%i",cmMakefile::GetMajorVersion(),
  1614. cmMakefile::GetMinorVersion());
  1615. this->CacheManager->AddCacheEntry
  1616. ("CMAKE_BACKWARDS_COMPATIBILITY",ver,
  1617. "For backwards compatibility, what version of CMake commands and "
  1618. "syntax should this version of CMake allow.",
  1619. cmCacheManager::STRING);
  1620. }
  1621. return 0;
  1622. }
  1623. void cmake::SetProgressCallback(ProgressCallbackType f, void *cd)
  1624. {
  1625. this->ProgressCallback = f;
  1626. this->ProgressCallbackClientData = cd;
  1627. }
  1628. void cmake::UpdateProgress(const char *msg, float prog)
  1629. {
  1630. if(this->ProgressCallback && !this->InTryCompile)
  1631. {
  1632. (*this->ProgressCallback)(msg, prog, this->ProgressCallbackClientData);
  1633. return;
  1634. }
  1635. }
  1636. void cmake::GetCommandDocumentation(
  1637. std::vector<cmDocumentationEntry>& v) const
  1638. {
  1639. for(RegisteredCommandsMap::const_iterator j = this->Commands.begin();
  1640. j != this->Commands.end(); ++j)
  1641. {
  1642. cmDocumentationEntry e =
  1643. {
  1644. (*j).second->GetName(),
  1645. (*j).second->GetTerseDocumentation(),
  1646. (*j).second->GetFullDocumentation()
  1647. };
  1648. v.push_back(e);
  1649. }
  1650. cmDocumentationEntry empty = {0,0,0};
  1651. v.push_back(empty);
  1652. }
  1653. void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
  1654. {
  1655. for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
  1656. i != this->Generators.end(); ++i)
  1657. {
  1658. cmDocumentationEntry e;
  1659. cmGlobalGenerator* generator = (i->second)();
  1660. generator->GetDocumentation(e);
  1661. delete generator;
  1662. v.push_back(e);
  1663. }
  1664. cmDocumentationEntry empty = {0,0,0};
  1665. v.push_back(empty);
  1666. }
  1667. void cmake::AddWrittenFile(const char* file)
  1668. {
  1669. this->WrittenFiles.insert(file);
  1670. }
  1671. bool cmake::HasWrittenFile(const char* file)
  1672. {
  1673. return this->WrittenFiles.find(file) != this->WrittenFiles.end();
  1674. }
  1675. void cmake::CleanupWrittenFiles()
  1676. {
  1677. this->WrittenFiles.clear();
  1678. }
  1679. void cmake::UpdateConversionPathTable()
  1680. {
  1681. // Update the path conversion table with any specified file:
  1682. const char* tablepath =
  1683. this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE");
  1684. if(tablepath)
  1685. {
  1686. std::ifstream table( tablepath );
  1687. if(!table)
  1688. {
  1689. cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", tablepath,
  1690. ". CMake can not open file.");
  1691. cmSystemTools::ReportLastSystemError("CMake can not open file.");
  1692. }
  1693. else
  1694. {
  1695. std::string a, b;
  1696. while(!table.eof())
  1697. {
  1698. // two entries per line
  1699. table >> a; table >> b;
  1700. cmSystemTools::AddTranslationPath( a.c_str(), b.c_str());
  1701. }
  1702. }
  1703. }
  1704. }
  1705. //----------------------------------------------------------------------------
  1706. int cmake::CheckBuildSystem()
  1707. {
  1708. // This method will check the integrity of the build system if the
  1709. // option was given on the command line. It reads the given file to
  1710. // determine whether CMake should rerun. If it does rerun then the
  1711. // generation step will check the integrity of dependencies. If it
  1712. // does not then we need to check the integrity here.
  1713. // If no file is provided for the check, we have to rerun.
  1714. if(this->CheckBuildSystemArgument.size() == 0)
  1715. {
  1716. return 1;
  1717. }
  1718. // If the file provided does not exist, we have to rerun.
  1719. if(!cmSystemTools::FileExists(this->CheckBuildSystemArgument.c_str()))
  1720. {
  1721. return 1;
  1722. }
  1723. // Read the rerun check file and use it to decide whether to do the
  1724. // global generate.
  1725. cmake cm;
  1726. cmGlobalGenerator gg;
  1727. gg.SetCMakeInstance(&cm);
  1728. std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
  1729. lg->SetGlobalGenerator(&gg);
  1730. cmMakefile* mf = lg->GetMakefile();
  1731. if(!mf->ReadListFile(0, this->CheckBuildSystemArgument.c_str()) ||
  1732. cmSystemTools::GetErrorOccuredFlag())
  1733. {
  1734. // There was an error reading the file. Just rerun.
  1735. return 1;
  1736. }
  1737. // Get the set of dependencies and outputs.
  1738. const char* dependsStr = mf->GetDefinition("CMAKE_MAKEFILE_DEPENDS");
  1739. const char* outputsStr = mf->GetDefinition("CMAKE_MAKEFILE_OUTPUTS");
  1740. if(!dependsStr || !outputsStr)
  1741. {
  1742. // Not enough information was provided to do the test. Just rerun.
  1743. return 1;
  1744. }
  1745. std::vector<std::string> depends;
  1746. std::vector<std::string> outputs;
  1747. cmSystemTools::ExpandListArgument(dependsStr, depends);
  1748. cmSystemTools::ExpandListArgument(outputsStr, outputs);
  1749. // If any output is older than any dependency then rerun.
  1750. for(std::vector<std::string>::iterator dep = depends.begin();
  1751. dep != depends.end(); ++dep)
  1752. {
  1753. for(std::vector<std::string>::iterator out = outputs.begin();
  1754. out != outputs.end(); ++out)
  1755. {
  1756. int result = 0;
  1757. if(!this->FileComparison->FileTimeCompare(out->c_str(),
  1758. dep->c_str(), &result) ||
  1759. result < 0)
  1760. {
  1761. return 1;
  1762. }
  1763. }
  1764. }
  1765. // We do not need to rerun CMake. Check dependency integrity. Use
  1766. // the make system's VERBOSE environment variable to enable verbose
  1767. // output.
  1768. bool verbose = cmSystemTools::GetEnv("VERBOSE") != 0;
  1769. // compute depends based on the generator specified
  1770. const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR");
  1771. if (!genName || genName[0] == '\0')
  1772. {
  1773. genName = "Unix Makefiles";
  1774. }
  1775. cmGlobalGenerator *ggd = this->CreateGlobalGenerator(genName);
  1776. if (ggd)
  1777. {
  1778. std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
  1779. lgd->SetGlobalGenerator(ggd);
  1780. lgd->CheckDependencies(mf, verbose, this->ClearBuildSystem);
  1781. }
  1782. // No need to rerun.
  1783. return 0;
  1784. }
  1785. //----------------------------------------------------------------------------
  1786. void cmake::TruncateOutputLog(const char* fname)
  1787. {
  1788. std::string fullPath = this->GetHomeOutputDirectory();
  1789. fullPath += "/";
  1790. fullPath += fname;
  1791. struct stat st;
  1792. if ( ::stat(fullPath.c_str(), &st) )
  1793. {
  1794. return;
  1795. }
  1796. if ( !this->CacheManager->GetCacheValue("CMAKE_CACHEFILE_DIR") )
  1797. {
  1798. cmSystemTools::RemoveFile(fullPath.c_str());
  1799. return;
  1800. }
  1801. size_t fsize = st.st_size;
  1802. const size_t maxFileSize = 50 * 1024;
  1803. if ( fsize < maxFileSize )
  1804. {
  1805. //TODO: truncate file
  1806. return;
  1807. }
  1808. }
  1809. inline std::string removeQuotes(const std::string& s)
  1810. {
  1811. if(s[0] == '\"' && s[s.size()-1] == '\"')
  1812. {
  1813. return s.substr(1, s.size()-2);
  1814. }
  1815. return s;
  1816. }
  1817. const char* cmake::GetCTestCommand()
  1818. {
  1819. if ( !this->CTestCommand.empty() )
  1820. {
  1821. return this->CTestCommand.c_str();
  1822. }
  1823. cmMakefile* mf
  1824. = this->GetGlobalGenerator()->GetLocalGenerator(0)->GetMakefile();
  1825. #ifdef CMAKE_BUILD_WITH_CMAKE
  1826. this->CTestCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
  1827. this->CTestCommand = removeQuotes(this->CTestCommand);
  1828. this->CTestCommand = cmSystemTools::GetFilenamePath(this->CTestCommand.c_str());
  1829. this->CTestCommand += "/";
  1830. this->CTestCommand += "ctest";
  1831. this->CTestCommand += cmSystemTools::GetExecutableExtension();
  1832. if(!cmSystemTools::FileExists(this->CTestCommand.c_str()))
  1833. {
  1834. this->CTestCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
  1835. this->CTestCommand = cmSystemTools::GetFilenamePath(this->CTestCommand.c_str());
  1836. this->CTestCommand += "/Debug/";
  1837. this->CTestCommand += "ctest";
  1838. this->CTestCommand += cmSystemTools::GetExecutableExtension();
  1839. }
  1840. if(!cmSystemTools::FileExists(this->CTestCommand.c_str()))
  1841. {
  1842. this->CTestCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
  1843. this->CTestCommand = cmSystemTools::GetFilenamePath(this->CTestCommand.c_str());
  1844. this->CTestCommand += "/Release/";
  1845. this->CTestCommand += "ctest";
  1846. this->CTestCommand += cmSystemTools::GetExecutableExtension();
  1847. }
  1848. #else
  1849. // Only for bootstrap
  1850. this->CTestCommand += mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
  1851. this->CTestCommand += "/ctest";
  1852. this->CTestCommand += cmSystemTools::GetExecutableExtension();
  1853. #endif
  1854. if ( this->CTestCommand.empty() )
  1855. {
  1856. cmSystemTools::Error("Cannot find the CTest executable");
  1857. this->CTestCommand = "CTEST-COMMAND-NOT-FOUND";
  1858. }
  1859. return this->CTestCommand.c_str();
  1860. }
  1861. const char* cmake::GetCPackCommand()
  1862. {
  1863. if ( !this->CPackCommand.empty() )
  1864. {
  1865. return this->CPackCommand.c_str();
  1866. }
  1867. cmMakefile* mf
  1868. = this->GetGlobalGenerator()->GetLocalGenerator(0)->GetMakefile();
  1869. #ifdef CMAKE_BUILD_WITH_CMAKE
  1870. this->CPackCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
  1871. this->CPackCommand = removeQuotes(this->CPackCommand);
  1872. this->CPackCommand = cmSystemTools::GetFilenamePath(this->CPackCommand.c_str());
  1873. this->CPackCommand += "/";
  1874. this->CPackCommand += "cpack";
  1875. this->CPackCommand += cmSystemTools::GetExecutableExtension();
  1876. if(!cmSystemTools::FileExists(this->CPackCommand.c_str()))
  1877. {
  1878. this->CPackCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
  1879. this->CPackCommand = cmSystemTools::GetFilenamePath(this->CPackCommand.c_str());
  1880. this->CPackCommand += "/Debug/";
  1881. this->CPackCommand += "cpack";
  1882. this->CPackCommand += cmSystemTools::GetExecutableExtension();
  1883. }
  1884. if(!cmSystemTools::FileExists(this->CPackCommand.c_str()))
  1885. {
  1886. this->CPackCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
  1887. this->CPackCommand = cmSystemTools::GetFilenamePath(this->CPackCommand.c_str());
  1888. this->CPackCommand += "/Release/";
  1889. this->CPackCommand += "cpack";
  1890. this->CPackCommand += cmSystemTools::GetExecutableExtension();
  1891. }
  1892. if (!cmSystemTools::FileExists(this->CPackCommand.c_str()))
  1893. {
  1894. cmSystemTools::Error("Cannot find the CPack executable");
  1895. this->CPackCommand = "CPACK-COMMAND-NOT-FOUND";
  1896. }
  1897. #else
  1898. // Only for bootstrap
  1899. this->CPackCommand += mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
  1900. this->CPackCommand += "/cpack";
  1901. this->CPackCommand += cmSystemTools::GetExecutableExtension();
  1902. #endif
  1903. return this->CPackCommand.c_str();
  1904. }
  1905. void cmake::GenerateGraphViz(const char* fileName)
  1906. {
  1907. cmGeneratedFileStream str(fileName);
  1908. if ( !str )
  1909. {
  1910. return;
  1911. }
  1912. cmake cm;
  1913. cmGlobalGenerator ggi;
  1914. ggi.SetCMakeInstance(&cm);
  1915. std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
  1916. lg->SetGlobalGenerator(&ggi);
  1917. cmMakefile *mf = lg->GetMakefile();
  1918. std::string infile = this->GetHomeOutputDirectory();
  1919. infile += "/CMakeGraphVizOptions.cmake";
  1920. if ( !cmSystemTools::FileExists(infile.c_str()) )
  1921. {
  1922. infile = this->GetHomeDirectory();
  1923. infile += "/CMakeGraphVizOptions.cmake";
  1924. if ( !cmSystemTools::FileExists(infile.c_str()) )
  1925. {
  1926. infile = "";
  1927. }
  1928. }
  1929. if ( !infile.empty() )
  1930. {
  1931. if ( !mf->ReadListFile(0, infile.c_str()) )
  1932. {
  1933. cmSystemTools::Error("Problem opening GraphViz options file: ",
  1934. infile.c_str());
  1935. return;
  1936. }
  1937. std::cout << "Read GraphViz options file: " << infile.c_str()
  1938. << std::endl;
  1939. }
  1940. #define __set_if_not_set(var, value, cmakeDefinition) \
  1941. const char* var = mf->GetDefinition(cmakeDefinition); \
  1942. if ( !var ) \
  1943. { \
  1944. var = value; \
  1945. }
  1946. __set_if_not_set(graphType, "digraph", "GRAPHVIZ_GRAPH_TYPE");
  1947. __set_if_not_set(graphName, "GG", "GRAPHVIZ_GRAPH_NAME");
  1948. __set_if_not_set(graphHeader, "node [\n fontsize = \"12\"\n];",
  1949. "GRAPHVIZ_GRAPH_HEADER");
  1950. __set_if_not_set(graphNodePrefix, "node", "GRAPHVIZ_NODE_PREFIX");
  1951. const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS");
  1952. std::set<cmStdString> ignoreTargetsSet;
  1953. if ( ignoreTargets )
  1954. {
  1955. std::vector<std::string> ignoreTargetsVector;
  1956. cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector);
  1957. std::vector<std::string>::iterator itvIt;
  1958. for ( itvIt = ignoreTargetsVector.begin();
  1959. itvIt != ignoreTargetsVector.end();
  1960. ++ itvIt )
  1961. {
  1962. ignoreTargetsSet.insert(itvIt->c_str());
  1963. }
  1964. }
  1965. str << graphType << " " << graphName << " {" << std::endl;
  1966. str << graphHeader << std::endl;
  1967. cmGlobalGenerator* gg = this->GetGlobalGenerator();
  1968. std::vector<cmLocalGenerator*> localGenerators;
  1969. gg->GetLocalGenerators(localGenerators);
  1970. std::vector<cmLocalGenerator*>::iterator lit;
  1971. // for target deps
  1972. // 1 - cmake target
  1973. // 2 - external target
  1974. // 0 - no deps
  1975. std::map<cmStdString, int> targetDeps;
  1976. std::map<cmStdString, cmTarget*> targetPtrs;
  1977. std::map<cmStdString, cmStdString> targetNamesNodes;
  1978. char tgtName[100];
  1979. int cnt = 0;
  1980. // First pass get the list of all cmake targets
  1981. for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit )
  1982. {
  1983. cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
  1984. cmTargets::iterator tit;
  1985. for ( tit = targets->begin(); tit != targets->end(); ++ tit )
  1986. {
  1987. const char* realTargetName = tit->first.c_str();
  1988. if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() )
  1989. {
  1990. // Skip ignored targets
  1991. continue;
  1992. }
  1993. //std::cout << "Found target: " << tit->first.c_str() << std::endl;
  1994. sprintf(tgtName, "%s%d", graphNodePrefix, cnt++);
  1995. targetNamesNodes[realTargetName] = tgtName;
  1996. targetPtrs[realTargetName] = &tit->second;
  1997. //str << " \"" << tgtName << "\" [ label=\"" << tit->first.c_str()
  1998. //<< "\" shape=\"box\"];" << std::endl;
  1999. }
  2000. }
  2001. // Ok, now find all the stuff we link to that is not in cmake
  2002. for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit )
  2003. {
  2004. cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
  2005. cmTargets::iterator tit;
  2006. for ( tit = targets->begin(); tit != targets->end(); ++ tit )
  2007. {
  2008. const cmTarget::LinkLibraryVectorType* ll
  2009. = &(tit->second.GetOriginalLinkLibraries());
  2010. cmTarget::LinkLibraryVectorType::const_iterator llit;
  2011. const char* realTargetName = tit->first.c_str();
  2012. if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() )
  2013. {
  2014. // Skip ignored targets
  2015. continue;
  2016. }
  2017. if ( ll->size() > 0 )
  2018. {
  2019. targetDeps[realTargetName] = 1;
  2020. }
  2021. for ( llit = ll->begin(); llit != ll->end(); ++ llit )
  2022. {
  2023. const char* libName = llit->first.c_str();
  2024. std::map<cmStdString, cmStdString>::iterator tarIt
  2025. = targetNamesNodes.find(libName);
  2026. if ( ignoreTargetsSet.find(libName) != ignoreTargetsSet.end() )
  2027. {
  2028. // Skip ignored targets
  2029. continue;
  2030. }
  2031. if ( tarIt == targetNamesNodes.end() )
  2032. {
  2033. sprintf(tgtName, "%s%d", graphNodePrefix, cnt++);
  2034. targetDeps[libName] = 2;
  2035. targetNamesNodes[libName] = tgtName;
  2036. //str << " \"" << tgtName << "\" [ label=\"" << libName
  2037. //<< "\" shape=\"ellipse\"];" << std::endl;
  2038. }
  2039. else
  2040. {
  2041. std::map<cmStdString, int>::iterator depIt
  2042. = targetDeps.find(libName);
  2043. if ( depIt == targetDeps.end() )
  2044. {
  2045. targetDeps[libName] = 1;
  2046. }
  2047. }
  2048. }
  2049. }
  2050. }
  2051. // Write out nodes
  2052. std::map<cmStdString, int>::iterator depIt;
  2053. for ( depIt = targetDeps.begin(); depIt != targetDeps.end(); ++ depIt )
  2054. {
  2055. const char* newTargetName = depIt->first.c_str();
  2056. std::map<cmStdString, cmStdString>::iterator tarIt
  2057. = targetNamesNodes.find(newTargetName);
  2058. if ( tarIt == targetNamesNodes.end() )
  2059. {
  2060. // We should not be here.
  2061. std::cout << __LINE__ << " Cannot find library: " << newTargetName
  2062. << " even though it was added in the previous pass" << std::endl;
  2063. abort();
  2064. }
  2065. str << " \"" << tarIt->second.c_str() << "\" [ label=\""
  2066. << newTargetName << "\" shape=\"";
  2067. if ( depIt->second == 1 )
  2068. {
  2069. std::map<cmStdString, cmTarget*>::iterator tarTypeIt= targetPtrs.find(
  2070. newTargetName);
  2071. if ( tarTypeIt == targetPtrs.end() )
  2072. {
  2073. // We should not be here.
  2074. std::cout << __LINE__ << " Cannot find library: " << newTargetName
  2075. << " even though it was added in the previous pass" << std::endl;
  2076. abort();
  2077. }
  2078. cmTarget* tg = tarTypeIt->second;
  2079. switch ( tg->GetType() )
  2080. {
  2081. case cmTarget::EXECUTABLE:
  2082. str << "house";
  2083. break;
  2084. case cmTarget::STATIC_LIBRARY:
  2085. str << "diamond";
  2086. break;
  2087. case cmTarget::SHARED_LIBRARY:
  2088. str << "polygon";
  2089. break;
  2090. case cmTarget::MODULE_LIBRARY:
  2091. str << "octagon";
  2092. break;
  2093. default:
  2094. str << "box";
  2095. }
  2096. }
  2097. else
  2098. {
  2099. str << "ellipse";
  2100. }
  2101. str << "\"];" << std::endl;
  2102. }
  2103. // Now generate the connectivity
  2104. for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit )
  2105. {
  2106. cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
  2107. cmTargets::iterator tit;
  2108. for ( tit = targets->begin(); tit != targets->end(); ++ tit )
  2109. {
  2110. std::map<cmStdString, int>::iterator dependIt
  2111. = targetDeps.find(tit->first.c_str());
  2112. if ( dependIt == targetDeps.end() )
  2113. {
  2114. continue;
  2115. }
  2116. std::map<cmStdString, cmStdString>::iterator cmakeTarIt
  2117. = targetNamesNodes.find(tit->first.c_str());
  2118. const cmTarget::LinkLibraryVectorType* ll
  2119. = &(tit->second.GetOriginalLinkLibraries());
  2120. cmTarget::LinkLibraryVectorType::const_iterator llit;
  2121. for ( llit = ll->begin(); llit != ll->end(); ++ llit )
  2122. {
  2123. const char* libName = llit->first.c_str();
  2124. std::map<cmStdString, cmStdString>::iterator tarIt
  2125. = targetNamesNodes.find(libName);
  2126. if ( tarIt == targetNamesNodes.end() )
  2127. {
  2128. // We should not be here.
  2129. std::cout << __LINE__ << " Cannot find library: " << libName
  2130. << " even though it was added in the previous pass" << std::endl;
  2131. abort();
  2132. }
  2133. str << " \"" << cmakeTarIt->second.c_str() << "\" -> \""
  2134. << tarIt->second.c_str() << "\"" << std::endl;
  2135. }
  2136. }
  2137. }
  2138. // TODO: Use dotted or something for external libraries
  2139. //str << " \"node0\":f4 -> \"node12\"[color=\"#0000ff\" style=dotted]"
  2140. //<< std::endl;
  2141. //
  2142. str << "}" << std::endl;
  2143. }