cmMakefile.cxx 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907
  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 "cmMakefile.h"
  14. #include "cmVersion.h"
  15. #include "cmCommand.h"
  16. #include "cmSourceFile.h"
  17. #include "cmSystemTools.h"
  18. #include "cmGlobalGenerator.h"
  19. #include "cmLocalGenerator.h"
  20. #include "cmCommands.h"
  21. #include "cmCacheManager.h"
  22. #include "cmFunctionBlocker.h"
  23. #include "cmListFileCache.h"
  24. #include "cmCommandArgumentParserHelper.h"
  25. #include "cmTest.h"
  26. #ifdef CMAKE_BUILD_WITH_CMAKE
  27. # include "cmVariableWatch.h"
  28. #endif
  29. #include "cmInstallGenerator.h"
  30. #include "cmake.h"
  31. #include <stdlib.h> // required for atoi
  32. #include <cmsys/RegularExpression.hxx>
  33. #include <ctype.h> // for isspace
  34. // default is not to be building executables
  35. cmMakefile::cmMakefile()
  36. {
  37. // Setup the default include file regular expression (match everything).
  38. this->IncludeFileRegularExpression = "^.*$";
  39. // Setup the default include complaint regular expression (match nothing).
  40. this->ComplainFileRegularExpression = "^$";
  41. // Source and header file extensions that we can handle
  42. // Set up a list of source and header extensions
  43. // these are used to find files when the extension
  44. // is not given
  45. // The "c" extension MUST precede the "C" extension.
  46. this->SourceFileExtensions.push_back( "c" );
  47. this->SourceFileExtensions.push_back( "C" );
  48. this->SourceFileExtensions.push_back( "c++" );
  49. this->SourceFileExtensions.push_back( "cc" );
  50. this->SourceFileExtensions.push_back( "cpp" );
  51. this->SourceFileExtensions.push_back( "cxx" );
  52. this->SourceFileExtensions.push_back( "m" );
  53. this->SourceFileExtensions.push_back( "M" );
  54. this->SourceFileExtensions.push_back( "mm" );
  55. this->HeaderFileExtensions.push_back( "h" );
  56. this->HeaderFileExtensions.push_back( "hh" );
  57. this->HeaderFileExtensions.push_back( "h++" );
  58. this->HeaderFileExtensions.push_back( "hm" );
  59. this->HeaderFileExtensions.push_back( "hpp" );
  60. this->HeaderFileExtensions.push_back( "hxx" );
  61. this->HeaderFileExtensions.push_back( "in" );
  62. this->HeaderFileExtensions.push_back( "txx" );
  63. this->DefineFlags = " ";
  64. this->LocalGenerator = 0;
  65. #if defined(CMAKE_BUILD_WITH_CMAKE)
  66. this->AddSourceGroup("", "^.*$");
  67. this->AddSourceGroup
  68. ("Source Files",
  69. "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
  70. this->AddSourceGroup("Header Files",
  71. "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
  72. this->AddSourceGroup("CMake Rules", "\\.rule$");
  73. this->AddSourceGroup("Resources", "\\.plist$");
  74. #endif
  75. this->AddDefaultDefinitions();
  76. this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
  77. this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
  78. this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
  79. this->PreOrder = false;
  80. }
  81. cmMakefile::cmMakefile(const cmMakefile& mf)
  82. {
  83. this->Prefix = mf.Prefix;
  84. this->AuxSourceDirectories = mf.AuxSourceDirectories;
  85. this->cmStartDirectory = mf.cmStartDirectory;
  86. this->StartOutputDirectory = mf.StartOutputDirectory;
  87. this->cmHomeDirectory = mf.cmHomeDirectory;
  88. this->HomeOutputDirectory = mf.HomeOutputDirectory;
  89. this->cmCurrentListFile = mf.cmCurrentListFile;
  90. this->ProjectName = mf.ProjectName;
  91. this->Targets = mf.Targets;
  92. this->SourceFiles = mf.SourceFiles;
  93. this->Tests = mf.Tests;
  94. this->IncludeDirectories = mf.IncludeDirectories;
  95. this->LinkDirectories = mf.LinkDirectories;
  96. this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
  97. this->ListFiles = mf.ListFiles;
  98. this->OutputFiles = mf.OutputFiles;
  99. this->LinkLibraries = mf.LinkLibraries;
  100. this->InstallGenerators = mf.InstallGenerators;
  101. this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
  102. this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
  103. this->SourceFileExtensions = mf.SourceFileExtensions;
  104. this->HeaderFileExtensions = mf.HeaderFileExtensions;
  105. this->DefineFlags = mf.DefineFlags;
  106. #if defined(CMAKE_BUILD_WITH_CMAKE)
  107. this->SourceGroups = mf.SourceGroups;
  108. #endif
  109. this->Definitions = mf.Definitions;
  110. this->LocalGenerator = mf.LocalGenerator;
  111. this->FunctionBlockers = mf.FunctionBlockers;
  112. this->DataMap = mf.DataMap;
  113. this->MacrosMap = mf.MacrosMap;
  114. this->SubDirectoryOrder = mf.SubDirectoryOrder;
  115. this->TemporaryDefinitionKey = mf.TemporaryDefinitionKey;
  116. this->Properties = mf.Properties;
  117. this->PreOrder = mf.PreOrder;
  118. this->ListFileStack = mf.ListFileStack;
  119. }
  120. unsigned int cmMakefile::GetCacheMajorVersion()
  121. {
  122. if(const char* vstr =
  123. this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
  124. {
  125. unsigned int v=0;
  126. if(sscanf(vstr, "%u", &v) == 1)
  127. {
  128. return v;
  129. }
  130. }
  131. return 0;
  132. }
  133. unsigned int cmMakefile::GetCacheMinorVersion()
  134. {
  135. if(const char* vstr =
  136. this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"))
  137. {
  138. unsigned int v=0;
  139. if(sscanf(vstr, "%u", &v) == 1)
  140. {
  141. return v;
  142. }
  143. }
  144. return 0;
  145. }
  146. cmMakefile::~cmMakefile()
  147. {
  148. for(std::vector<cmInstallGenerator*>::iterator
  149. i = this->InstallGenerators.begin();
  150. i != this->InstallGenerators.end(); ++i)
  151. {
  152. delete *i;
  153. }
  154. for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
  155. i != this->SourceFiles.end(); ++i)
  156. {
  157. delete *i;
  158. }
  159. for(std::vector<cmTest*>::iterator i = this->Tests.begin();
  160. i != this->Tests.end(); ++i)
  161. {
  162. delete *i;
  163. }
  164. for(unsigned int i=0; i < this->UsedCommands.size(); i++)
  165. {
  166. delete this->UsedCommands[i];
  167. }
  168. for(DataMapType::const_iterator d = this->DataMap.begin();
  169. d != this->DataMap.end(); ++d)
  170. {
  171. if(d->second)
  172. {
  173. delete d->second;
  174. }
  175. }
  176. std::list<cmFunctionBlocker *>::iterator pos;
  177. for (pos = this->FunctionBlockers.begin();
  178. pos != this->FunctionBlockers.end(); ++pos)
  179. {
  180. cmFunctionBlocker* b = *pos;
  181. delete b;
  182. }
  183. this->FunctionBlockers.clear();
  184. }
  185. void cmMakefile::PrintStringVector(const char* s,
  186. const std::vector<std::string>& v) const
  187. {
  188. std::cout << s << ": ( \n";
  189. for(std::vector<std::string>::const_iterator i = v.begin();
  190. i != v.end(); ++i)
  191. {
  192. std::cout << (*i).c_str() << " ";
  193. }
  194. std::cout << " )\n";
  195. }
  196. void cmMakefile
  197. ::PrintStringVector(const char* s,
  198. const std::vector<std::pair<cmStdString, bool> >& v) const
  199. {
  200. std::cout << s << ": ( \n";
  201. for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
  202. = v.begin(); i != v.end(); ++i)
  203. {
  204. std::cout << i->first.c_str() << " " << i->second;
  205. }
  206. std::cout << " )\n";
  207. }
  208. // call print on all the classes in the makefile
  209. void cmMakefile::Print()
  210. {
  211. // print the class lists
  212. std::cout << "classes:\n";
  213. std::cout << " this->Targets: ";
  214. for (cmTargets::iterator l = this->Targets.begin();
  215. l != this->Targets.end(); l++)
  216. {
  217. std::cout << l->first << std::endl;
  218. }
  219. std::cout << " this->StartOutputDirectory; " <<
  220. this->StartOutputDirectory.c_str() << std::endl;
  221. std::cout << " this->HomeOutputDirectory; " <<
  222. this->HomeOutputDirectory.c_str() << std::endl;
  223. std::cout << " this->cmStartDirectory; " <<
  224. this->cmStartDirectory.c_str() << std::endl;
  225. std::cout << " this->cmHomeDirectory; " <<
  226. this->cmHomeDirectory.c_str() << std::endl;
  227. std::cout << " this->ProjectName; "
  228. << this->ProjectName.c_str() << std::endl;
  229. this->PrintStringVector("this->IncludeDirectories;",
  230. this->IncludeDirectories);
  231. this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
  232. #if defined(CMAKE_BUILD_WITH_CMAKE)
  233. for( std::vector<cmSourceGroup>::const_iterator i =
  234. this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
  235. {
  236. std::cout << "Source Group: " << i->GetName() << std::endl;
  237. }
  238. #endif
  239. }
  240. bool cmMakefile::CommandExists(const char* name) const
  241. {
  242. return this->GetCMakeInstance()->CommandExists(name);
  243. }
  244. bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
  245. {
  246. bool result = true;
  247. // quick return if blocked
  248. if(this->IsFunctionBlocked(lff))
  249. {
  250. // No error.
  251. return result;
  252. }
  253. std::string name = lff.Name;
  254. // execute the command
  255. cmCommand *rm =
  256. this->GetCMakeInstance()->GetCommand(name.c_str());
  257. if(rm)
  258. {
  259. const char* versionValue
  260. = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
  261. int major = 0;
  262. int minor = 0;
  263. if ( versionValue )
  264. {
  265. sscanf(versionValue, "%d.%d", &major, &minor);
  266. }
  267. if ( rm->IsDeprecated(major, minor) )
  268. {
  269. cmOStringStream error;
  270. error << "Error in cmake code at\n"
  271. << lff.FilePath << ":" << lff.Line << ":\n"
  272. << rm->GetError() << std::endl
  273. << "Current CMake stack: " << this->GetListFileStack().c_str();
  274. cmSystemTools::Error(error.str().c_str());
  275. return false;
  276. }
  277. cmCommand* usedCommand = rm->Clone();
  278. usedCommand->SetMakefile(this);
  279. bool keepCommand = false;
  280. if(usedCommand->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
  281. (!this->GetCMakeInstance()->GetScriptMode() ||
  282. usedCommand->IsScriptable()))
  283. {
  284. if(!usedCommand->InvokeInitialPass(lff.Arguments))
  285. {
  286. cmOStringStream error;
  287. error << "Error in cmake code at\n"
  288. << lff.FilePath << ":" << lff.Line << ":\n"
  289. << usedCommand->GetError() << std::endl
  290. << "Current CMake stack: " << this->GetListFileStack().c_str();
  291. cmSystemTools::Error(error.str().c_str());
  292. result = false;
  293. if ( this->GetCMakeInstance()->GetScriptMode() )
  294. {
  295. cmSystemTools::SetFatalErrorOccured();
  296. }
  297. }
  298. else
  299. {
  300. // use the command
  301. keepCommand = true;
  302. this->UsedCommands.push_back(usedCommand);
  303. }
  304. }
  305. else if ( this->GetCMakeInstance()->GetScriptMode()
  306. && !usedCommand->IsScriptable() )
  307. {
  308. cmOStringStream error;
  309. error << "Error in cmake code at\n"
  310. << lff.FilePath << ":" << lff.Line << ":\n"
  311. << "Command " << usedCommand->GetName()
  312. << " not scriptable" << std::endl;
  313. cmSystemTools::Error(error.str().c_str());
  314. result = false;
  315. cmSystemTools::SetFatalErrorOccured();
  316. }
  317. // if the Cloned command was not used
  318. // then delete it
  319. if(!keepCommand)
  320. {
  321. delete usedCommand;
  322. }
  323. }
  324. else
  325. {
  326. if(!cmSystemTools::GetFatalErrorOccured())
  327. {
  328. cmOStringStream error;
  329. error << "Error in cmake code at\n"
  330. << lff.FilePath << ":" << lff.Line << ":\n"
  331. << "Unknown CMake command \"" << lff.Name.c_str() << "\".";
  332. cmSystemTools::Error(error.str().c_str());
  333. result = false;
  334. cmSystemTools::SetFatalErrorOccured();
  335. }
  336. }
  337. return result;
  338. }
  339. // Parse the given CMakeLists.txt file executing all commands
  340. //
  341. bool cmMakefile::ReadListFile(const char* filename_in,
  342. const char *external_in,
  343. std::string* fullPath)
  344. {
  345. std::string currentParentFile
  346. = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
  347. std::string currentFile
  348. = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
  349. this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
  350. // used to watch for blockers going out of scope
  351. // e.g. mismatched IF statement
  352. std::set<cmFunctionBlocker *> originalBlockers;
  353. const char* external = 0;
  354. std::string external_abs;
  355. const char* filename = filename_in;
  356. std::string filename_abs;
  357. if (external_in)
  358. {
  359. external_abs =
  360. cmSystemTools::CollapseFullPath(external_in,
  361. this->cmStartDirectory.c_str());
  362. external = external_abs.c_str();
  363. if (filename_in)
  364. {
  365. filename_abs =
  366. cmSystemTools::CollapseFullPath(filename_in,
  367. this->cmStartDirectory.c_str());
  368. filename = filename_abs.c_str();
  369. }
  370. }
  371. // keep track of the current file being read
  372. if (filename)
  373. {
  374. if(this->cmCurrentListFile != filename)
  375. {
  376. this->cmCurrentListFile = filename;
  377. }
  378. // loop over current function blockers and record them
  379. std::list<cmFunctionBlocker *>::iterator pos;
  380. for (pos = this->FunctionBlockers.begin();
  381. pos != this->FunctionBlockers.end(); ++pos)
  382. {
  383. originalBlockers.insert(*pos);
  384. }
  385. }
  386. // Now read the input file
  387. const char *filenametoread= filename;
  388. if( external)
  389. {
  390. filenametoread= external;
  391. }
  392. this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
  393. // try to see if the list file is the top most
  394. // list file for a project, and if it is, then it
  395. // must have a project command. If there is not
  396. // one, then cmake will provide one via the
  397. // cmListFileCache class.
  398. bool requireProjectCommand = false;
  399. if(!external && this->cmStartDirectory == this->cmHomeDirectory)
  400. {
  401. if(cmSystemTools::LowerCase(
  402. cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
  403. {
  404. requireProjectCommand = true;
  405. }
  406. }
  407. // push the listfile onto the stack
  408. this->ListFileStack.push_back(filenametoread);
  409. if(fullPath!=0)
  410. {
  411. *fullPath=filenametoread;
  412. }
  413. cmListFile cacheFile;
  414. if( !cacheFile.ParseFile(filenametoread, requireProjectCommand) )
  415. {
  416. // pop the listfile off the stack
  417. this->ListFileStack.pop_back();
  418. if(fullPath!=0)
  419. {
  420. *fullPath = "";
  421. }
  422. this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
  423. this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
  424. return false;
  425. }
  426. // add this list file to the list of dependencies
  427. this->ListFiles.push_back( filenametoread);
  428. const size_t numberFunctions = cacheFile.Functions.size();
  429. for(size_t i =0; i < numberFunctions; ++i)
  430. {
  431. this->ExecuteCommand(cacheFile.Functions[i]);
  432. if ( cmSystemTools::GetFatalErrorOccured() )
  433. {
  434. // pop the listfile off the stack
  435. this->ListFileStack.pop_back();
  436. this->AddDefinition("CMAKE_PARENT_LIST_FILE",
  437. currentParentFile.c_str());
  438. this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
  439. return true;
  440. }
  441. }
  442. // send scope ended to and function blockers
  443. if (filename)
  444. {
  445. // loop over all function blockers to see if any block this command
  446. std::list<cmFunctionBlocker *>::iterator pos;
  447. for (pos = this->FunctionBlockers.begin();
  448. pos != this->FunctionBlockers.end(); ++pos)
  449. {
  450. // if this blocker was not in the original then send a
  451. // scope ended message
  452. if (originalBlockers.find(*pos) == originalBlockers.end())
  453. {
  454. (*pos)->ScopeEnded(*this);
  455. }
  456. }
  457. }
  458. this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
  459. this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
  460. // pop the listfile off the stack
  461. this->ListFileStack.pop_back();
  462. return true;
  463. }
  464. void cmMakefile::AddCommand(cmCommand* wg)
  465. {
  466. this->GetCMakeInstance()->AddCommand(wg);
  467. }
  468. // Set the make file
  469. void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
  470. {
  471. this->LocalGenerator = lg;
  472. }
  473. void cmMakefile::FinalPass()
  474. {
  475. // do all the variable expansions here
  476. this->ExpandVariables();
  477. // give all the commands a chance to do something
  478. // after the file has been parsed before generation
  479. for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin();
  480. i != this->UsedCommands.end(); ++i)
  481. {
  482. (*i)->FinalPass();
  483. }
  484. }
  485. // Generate the output file
  486. void cmMakefile::ConfigureFinalPass()
  487. {
  488. this->FinalPass();
  489. const char* oldValue
  490. = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
  491. if (oldValue && atof(oldValue) <= 1.2)
  492. {
  493. cmSystemTools::Error("You have requested backwards compatibility "
  494. "with CMake version 1.2 or earlier. This version "
  495. "of CMake only supports backwards compatibility "
  496. "with CMake 1.4 or later. For compatibility with "
  497. "1.2 or earlier please use CMake 2.0");
  498. }
  499. for (cmTargets::iterator l = this->Targets.begin();
  500. l != this->Targets.end(); l++)
  501. {
  502. l->second.GenerateSourceFilesFromSourceLists(*this);
  503. l->second.AnalyzeLibDependencies(*this);
  504. }
  505. }
  506. //----------------------------------------------------------------------------
  507. void
  508. cmMakefile::AddCustomCommandToTarget(const char* target,
  509. const std::vector<std::string>& depends,
  510. const cmCustomCommandLines& commandLines,
  511. cmTarget::CustomCommandType type,
  512. const char* comment,
  513. const char* workingDir,
  514. bool escapeOldStyle)
  515. {
  516. // Find the target to which to add the custom command.
  517. cmTargets::iterator ti = this->Targets.find(target);
  518. if(ti != this->Targets.end())
  519. {
  520. // Add the command to the appropriate build step for the target.
  521. std::vector<std::string> no_output;
  522. cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
  523. cc.SetEscapeOldStyle(escapeOldStyle);
  524. switch(type)
  525. {
  526. case cmTarget::PRE_BUILD:
  527. ti->second.GetPreBuildCommands().push_back(cc);
  528. break;
  529. case cmTarget::PRE_LINK:
  530. ti->second.GetPreLinkCommands().push_back(cc);
  531. break;
  532. case cmTarget::POST_BUILD:
  533. ti->second.GetPostBuildCommands().push_back(cc);
  534. break;
  535. }
  536. }
  537. }
  538. //----------------------------------------------------------------------------
  539. void
  540. cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
  541. const std::vector<std::string>& depends,
  542. const char* main_dependency,
  543. const cmCustomCommandLines& commandLines,
  544. const char* comment,
  545. const char* workingDir,
  546. bool replace,
  547. bool escapeOldStyle)
  548. {
  549. // Make sure there is at least one output.
  550. if(outputs.empty())
  551. {
  552. cmSystemTools::Error("Attempt to add a custom rule with no output!");
  553. return;
  554. }
  555. // Choose a source file on which to store the custom command.
  556. cmSourceFile* file = 0;
  557. if(main_dependency && main_dependency[0])
  558. {
  559. // The main dependency was specified. Use it unless a different
  560. // custom command already used it.
  561. file = this->GetSource(main_dependency);
  562. if(file && file->GetCustomCommand() && !replace)
  563. {
  564. // The main dependency already has a custom command.
  565. if(commandLines == file->GetCustomCommand()->GetCommandLines())
  566. {
  567. // The existing custom command is identical. Silently ignore
  568. // the duplicate.
  569. return;
  570. }
  571. else
  572. {
  573. // The existing custom command is different. We need to
  574. // generate a rule file for this new command.
  575. file = 0;
  576. }
  577. }
  578. else
  579. {
  580. // The main dependency does not have a custom command or we are
  581. // allowed to replace it. Use it to store the command.
  582. file = this->GetOrCreateSource(main_dependency);
  583. }
  584. }
  585. // Generate a rule file if the main dependency is not available.
  586. if(!file)
  587. {
  588. // Construct a rule file associated with the first output produced.
  589. std::string outName = outputs[0];
  590. outName += ".rule";
  591. // Check if the rule file already exists.
  592. file = this->GetSource(outName.c_str());
  593. if(file && file->GetCustomCommand() && !replace)
  594. {
  595. // The rule file already exists.
  596. if(commandLines != file->GetCustomCommand()->GetCommandLines())
  597. {
  598. cmSystemTools::Error("Attempt to add a custom rule to output \"",
  599. outName.c_str(),
  600. "\" which already has a custom rule.");
  601. }
  602. return;
  603. }
  604. // Create a cmSourceFile for the rule file.
  605. file = this->GetOrCreateSource(outName.c_str(), true);
  606. }
  607. // Always create the output sources and mark them generated.
  608. for(std::vector<std::string>::const_iterator o = outputs.begin();
  609. o != outputs.end(); ++o)
  610. {
  611. if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
  612. {
  613. out->SetProperty("GENERATED", "1");
  614. }
  615. }
  616. // Construct a complete list of dependencies.
  617. std::vector<std::string> depends2(depends);
  618. if(main_dependency && main_dependency[0])
  619. {
  620. depends2.push_back(main_dependency);
  621. }
  622. // Attach the custom command to the file.
  623. if(file)
  624. {
  625. cmCustomCommand* cc =
  626. new cmCustomCommand(outputs, depends2, commandLines,
  627. comment, workingDir);
  628. cc->SetEscapeOldStyle(escapeOldStyle);
  629. file->SetCustomCommand(cc);
  630. }
  631. }
  632. //----------------------------------------------------------------------------
  633. void
  634. cmMakefile::AddCustomCommandToOutput(const char* output,
  635. const std::vector<std::string>& depends,
  636. const char* main_dependency,
  637. const cmCustomCommandLines& commandLines,
  638. const char* comment,
  639. const char* workingDir,
  640. bool replace,
  641. bool escapeOldStyle)
  642. {
  643. std::vector<std::string> outputs;
  644. outputs.push_back(output);
  645. this->AddCustomCommandToOutput(outputs, depends, main_dependency,
  646. commandLines, comment, workingDir,
  647. replace, escapeOldStyle);
  648. }
  649. //----------------------------------------------------------------------------
  650. void
  651. cmMakefile::AddCustomCommandOldStyle(const char* target,
  652. const std::vector<std::string>& outputs,
  653. const std::vector<std::string>& depends,
  654. const char* source,
  655. const cmCustomCommandLines& commandLines,
  656. const char* comment)
  657. {
  658. // Translate the old-style signature to one of the new-style
  659. // signatures.
  660. if(strcmp(source, target) == 0)
  661. {
  662. // In the old-style signature if the source and target were the
  663. // same then it added a post-build rule to the target. Preserve
  664. // this behavior.
  665. this->AddCustomCommandToTarget(target, depends, commandLines,
  666. cmTarget::POST_BUILD, comment, 0);
  667. return;
  668. }
  669. // Each output must get its own copy of this rule.
  670. cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
  671. "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
  672. "hm|hpp|hxx|in|txx|inl)$");
  673. for(std::vector<std::string>::const_iterator oi = outputs.begin();
  674. oi != outputs.end(); ++oi)
  675. {
  676. // Get the name of this output.
  677. const char* output = oi->c_str();
  678. // Choose whether to use a main dependency.
  679. if(sourceFiles.find(source))
  680. {
  681. // The source looks like a real file. Use it as the main dependency.
  682. this->AddCustomCommandToOutput(output, depends, source,
  683. commandLines, comment, 0);
  684. }
  685. else
  686. {
  687. // The source may not be a real file. Do not use a main dependency.
  688. const char* no_main_dependency = 0;
  689. std::vector<std::string> depends2 = depends;
  690. depends2.push_back(source);
  691. this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
  692. commandLines, comment, 0);
  693. }
  694. // If the rule was added to the source (and not a .rule file),
  695. // then add the source to the target to make sure the rule is
  696. // included.
  697. std::string sname = output;
  698. sname += ".rule";
  699. if(!this->GetSource(sname.c_str()))
  700. {
  701. if (this->Targets.find(target) != this->Targets.end())
  702. {
  703. this->Targets[target].AddSourceListEntry(source);
  704. }
  705. else
  706. {
  707. cmSystemTools::Error("Attempt to add a custom rule to a target "
  708. "that does not exist yet for target ", target);
  709. return;
  710. }
  711. }
  712. }
  713. }
  714. //----------------------------------------------------------------------------
  715. void cmMakefile::AddUtilityCommand(const char* utilityName,
  716. bool excludeFromAll,
  717. const std::vector<std::string>& depends,
  718. const char* workingDirectory,
  719. const char* command,
  720. const char* arg1,
  721. const char* arg2,
  722. const char* arg3,
  723. const char* arg4)
  724. {
  725. // Construct the command line for the custom command.
  726. cmCustomCommandLine commandLine;
  727. commandLine.push_back(command);
  728. if(arg1)
  729. {
  730. commandLine.push_back(arg1);
  731. }
  732. if(arg2)
  733. {
  734. commandLine.push_back(arg2);
  735. }
  736. if(arg3)
  737. {
  738. commandLine.push_back(arg3);
  739. }
  740. if(arg4)
  741. {
  742. commandLine.push_back(arg4);
  743. }
  744. cmCustomCommandLines commandLines;
  745. commandLines.push_back(commandLine);
  746. // Call the real signature of this method.
  747. this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
  748. depends, commandLines);
  749. }
  750. //----------------------------------------------------------------------------
  751. void cmMakefile::AddUtilityCommand(const char* utilityName,
  752. bool excludeFromAll,
  753. const char* workingDirectory,
  754. const std::vector<std::string>& depends,
  755. const cmCustomCommandLines& commandLines,
  756. bool escapeOldStyle, const char* comment)
  757. {
  758. // Create a target instance for this utility.
  759. cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName, false);
  760. if (excludeFromAll)
  761. {
  762. target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
  763. }
  764. if(!comment)
  765. {
  766. // Use an empty comment to avoid generation of default comment.
  767. comment = "";
  768. }
  769. // Store the custom command in the target.
  770. std::string force = this->GetStartOutputDirectory();
  771. force += cmake::GetCMakeFilesDirectory();
  772. force += "/";
  773. force += utilityName;
  774. const char* no_main_dependency = 0;
  775. bool no_replace = false;
  776. this->AddCustomCommandToOutput(force.c_str(), depends,
  777. no_main_dependency,
  778. commandLines, comment,
  779. workingDirectory, no_replace,
  780. escapeOldStyle);
  781. target->AddSourceListEntry(force.c_str());
  782. // The output is not actually created so mark it symbolic.
  783. if(cmSourceFile* sf = this->GetSource(force.c_str()))
  784. {
  785. sf->SetProperty("SYMBOLIC", "1");
  786. }
  787. else
  788. {
  789. cmSystemTools::Error("Could not get source file entry for ",
  790. force.c_str());
  791. }
  792. }
  793. void cmMakefile::AddDefineFlag(const char* flag)
  794. {
  795. if (!flag)
  796. {
  797. return;
  798. }
  799. // remove any \n\r
  800. std::string ret = flag;
  801. std::string::size_type pos = 0;
  802. while((pos = ret.find('\n', pos)) != std::string::npos)
  803. {
  804. ret[pos] = ' ';
  805. pos++;
  806. }
  807. pos = 0;
  808. while((pos = ret.find('\r', pos)) != std::string::npos)
  809. {
  810. ret[pos] = ' ';
  811. pos++;
  812. }
  813. this->DefineFlags += " ";
  814. this->DefineFlags += ret;
  815. }
  816. void cmMakefile::RemoveDefineFlag(const char* flag)
  817. {
  818. // Check the length of the flag to remove.
  819. std::string::size_type len = strlen(flag);
  820. if(len < 1)
  821. {
  822. return;
  823. }
  824. // Remove all instances of the flag that are surrounded by
  825. // whitespace or the beginning/end of the string.
  826. for(std::string::size_type lpos = this->DefineFlags.find(flag, 0);
  827. lpos != std::string::npos; lpos = this->DefineFlags.find(flag, lpos))
  828. {
  829. std::string::size_type rpos = lpos + len;
  830. if((lpos <= 0 || isspace(this->DefineFlags[lpos-1])) &&
  831. (rpos >= this->DefineFlags.size() || isspace(this->DefineFlags[rpos])))
  832. {
  833. this->DefineFlags.erase(lpos, len);
  834. }
  835. else
  836. {
  837. ++lpos;
  838. }
  839. }
  840. }
  841. void cmMakefile::AddLinkLibrary(const char* lib,
  842. cmTarget::LinkLibraryType llt)
  843. {
  844. cmTarget::LibraryID tmp;
  845. tmp.first = lib;
  846. tmp.second = llt;
  847. this->LinkLibraries.push_back(tmp);
  848. }
  849. void cmMakefile::AddLinkLibraryForTarget(const char *target,
  850. const char* lib,
  851. cmTarget::LinkLibraryType llt)
  852. {
  853. cmTargets::iterator i = this->Targets.find(target);
  854. if ( i != this->Targets.end())
  855. {
  856. cmTarget* tgt =
  857. this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0, lib, false);
  858. if(tgt)
  859. {
  860. bool allowModules = true;
  861. const char* versionValue
  862. = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
  863. if (versionValue && (atof(versionValue) >= 2.4) )
  864. {
  865. allowModules = false;
  866. }
  867. // if it is not a static or shared library then you can not link to it
  868. if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
  869. (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
  870. (tgt->GetType() == cmTarget::EXECUTABLE &&
  871. tgt->GetPropertyAsBool("ENABLE_EXPORTS"))))
  872. {
  873. cmOStringStream e;
  874. e << "Attempt to add link target " << lib << " of type: "
  875. << cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
  876. << "\nto target " << target
  877. << ". One can only link to STATIC or SHARED libraries, or "
  878. << "to executables with the ENABLE_EXPORTS property set.";
  879. // in older versions of cmake linking to modules was allowed
  880. if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
  881. {
  882. e <<
  883. "\nTo allow linking of modules set "
  884. "CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower\n";
  885. }
  886. // if no modules are allowed then this is always an error
  887. if(!allowModules ||
  888. // if we allow modules but the type is not a module then it is
  889. // still an error
  890. (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
  891. {
  892. cmSystemTools::Error(e.str().c_str());
  893. }
  894. }
  895. }
  896. i->second.AddLinkLibrary( *this, target, lib, llt );
  897. }
  898. else
  899. {
  900. cmOStringStream e;
  901. e << "Attempt to add link library \""
  902. << lib << "\" to target \""
  903. << target << "\" which is not built by this project.";
  904. cmSystemTools::Error(e.str().c_str());
  905. }
  906. }
  907. void cmMakefile::AddLinkDirectoryForTarget(const char *target,
  908. const char* d)
  909. {
  910. cmTargets::iterator i = this->Targets.find(target);
  911. if ( i != this->Targets.end())
  912. {
  913. i->second.AddLinkDirectory( d );
  914. }
  915. else
  916. {
  917. cmSystemTools::Error
  918. ("Attempt to add link directories to non-existant target: ",
  919. target, " for directory ", d);
  920. }
  921. }
  922. void cmMakefile::AddLinkLibrary(const char* lib)
  923. {
  924. this->AddLinkLibrary(lib,cmTarget::GENERAL);
  925. }
  926. void cmMakefile::AddLinkDirectory(const char* dir)
  927. {
  928. // Don't add a link directory that is already present. Yes, this
  929. // linear search results in n^2 behavior, but n won't be getting
  930. // much bigger than 20. We cannot use a set because of order
  931. // dependency of the link search path.
  932. // remove trailing slashes
  933. if(dir && dir[strlen(dir)-1] == '/')
  934. {
  935. std::string newdir = dir;
  936. newdir = newdir.substr(0, newdir.size()-1);
  937. if(std::find(this->LinkDirectories.begin(),
  938. this->LinkDirectories.end(),
  939. newdir.c_str()) == this->LinkDirectories.end())
  940. {
  941. this->LinkDirectories.push_back(newdir);
  942. }
  943. }
  944. else
  945. {
  946. if(std::find(this->LinkDirectories.begin(),
  947. this->LinkDirectories.end(), dir)
  948. == this->LinkDirectories.end())
  949. {
  950. this->LinkDirectories.push_back(dir);
  951. }
  952. }
  953. }
  954. void cmMakefile::InitializeFromParent()
  955. {
  956. cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
  957. // copy the definitions
  958. this->Definitions = parent->Definitions;
  959. // copy include paths
  960. this->IncludeDirectories = parent->IncludeDirectories;
  961. this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
  962. // define flags
  963. this->DefineFlags = parent->DefineFlags;
  964. // link libraries
  965. this->LinkLibraries = parent->LinkLibraries;
  966. // link directories
  967. this->LinkDirectories = parent->LinkDirectories;
  968. // the initial project name
  969. this->ProjectName = parent->ProjectName;
  970. // Copy include regular expressions.
  971. this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
  972. this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
  973. }
  974. void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
  975. {
  976. // copy our variables from the child makefile
  977. lg2->GetMakefile()->InitializeFromParent();
  978. lg2->GetMakefile()->MakeStartDirectoriesCurrent();
  979. // finally configure the subdir
  980. lg2->Configure();
  981. }
  982. void cmMakefile::AddSubDirectory(const char* sub,
  983. bool excludeFromAll, bool preorder)
  984. {
  985. // the source path must be made full if it isn't already
  986. std::string srcPath = sub;
  987. if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
  988. {
  989. srcPath = this->GetCurrentDirectory();
  990. srcPath += "/";
  991. srcPath += sub;
  992. }
  993. // binary path must be made full if it isn't already
  994. std::string binPath = sub;
  995. if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
  996. {
  997. binPath = this->GetCurrentOutputDirectory();
  998. binPath += "/";
  999. binPath += sub;
  1000. }
  1001. this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
  1002. excludeFromAll, preorder, false);
  1003. }
  1004. void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
  1005. bool excludeFromAll, bool preorder,
  1006. bool immediate)
  1007. {
  1008. std::vector<cmLocalGenerator *>& children =
  1009. this->LocalGenerator->GetChildren();
  1010. // has this directory already been added? If so error
  1011. unsigned int i;
  1012. for (i = 0; i < children.size(); ++i)
  1013. {
  1014. if (srcPath == children[i]->GetMakefile()->GetStartDirectory())
  1015. {
  1016. cmSystemTools::Error
  1017. ("Attempt to add subdirectory multiple times for directory.\n",
  1018. srcPath);
  1019. return;
  1020. }
  1021. }
  1022. // create a new local generator and set its parent
  1023. cmLocalGenerator *lg2 =
  1024. this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
  1025. lg2->SetParent(this->LocalGenerator);
  1026. this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
  1027. // set the subdirs start dirs
  1028. lg2->GetMakefile()->SetStartDirectory(srcPath);
  1029. lg2->GetMakefile()->SetStartOutputDirectory(binPath);
  1030. if(excludeFromAll)
  1031. {
  1032. lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
  1033. }
  1034. lg2->GetMakefile()->SetPreOrder(preorder);
  1035. if (immediate)
  1036. {
  1037. this->ConfigureSubDirectory(lg2);
  1038. }
  1039. }
  1040. void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
  1041. {
  1042. // if there is a newline then break it into multiple arguments
  1043. if (!inc)
  1044. {
  1045. return;
  1046. }
  1047. // Don't add an include directory that is already present. Yes,
  1048. // this linear search results in n^2 behavior, but n won't be
  1049. // getting much bigger than 20. We cannot use a set because of
  1050. // order dependency of the include path.
  1051. std::vector<std::string>::iterator i =
  1052. std::find(this->IncludeDirectories.begin(),
  1053. this->IncludeDirectories.end(), inc);
  1054. if(i == this->IncludeDirectories.end())
  1055. {
  1056. if (before)
  1057. {
  1058. // WARNING: this *is* expensive (linear time) since it's a vector
  1059. this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
  1060. }
  1061. else
  1062. {
  1063. this->IncludeDirectories.push_back(inc);
  1064. }
  1065. }
  1066. else
  1067. {
  1068. if(before)
  1069. {
  1070. // if this before and already in the path then remove it
  1071. this->IncludeDirectories.erase(i);
  1072. // WARNING: this *is* expensive (linear time) since it's a vector
  1073. this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
  1074. }
  1075. }
  1076. }
  1077. //----------------------------------------------------------------------------
  1078. void cmMakefile::AddSystemIncludeDirectory(const char* dir)
  1079. {
  1080. this->SystemIncludeDirectories.insert(dir);
  1081. }
  1082. //----------------------------------------------------------------------------
  1083. bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
  1084. {
  1085. return (this->SystemIncludeDirectories.find(dir) !=
  1086. this->SystemIncludeDirectories.end());
  1087. }
  1088. void cmMakefile::AddDefinition(const char* name, const char* value)
  1089. {
  1090. if (!value )
  1091. {
  1092. return;
  1093. }
  1094. this->TemporaryDefinitionKey = name;
  1095. this->Definitions[this->TemporaryDefinitionKey] = value;
  1096. #ifdef CMAKE_BUILD_WITH_CMAKE
  1097. cmVariableWatch* vv = this->GetVariableWatch();
  1098. if ( vv )
  1099. {
  1100. vv->VariableAccessed(this->TemporaryDefinitionKey,
  1101. cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
  1102. value,
  1103. this);
  1104. }
  1105. #endif
  1106. }
  1107. void cmMakefile::AddCacheDefinition(const char* name, const char* value,
  1108. const char* doc,
  1109. cmCacheManager::CacheEntryType type)
  1110. {
  1111. const char* val = value;
  1112. cmCacheManager::CacheIterator it =
  1113. this->GetCacheManager()->GetCacheIterator(name);
  1114. if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
  1115. it.Initialized())
  1116. {
  1117. val = it.GetValue();
  1118. if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
  1119. {
  1120. std::vector<std::string>::size_type cc;
  1121. std::vector<std::string> files;
  1122. std::string nvalue = "";
  1123. cmSystemTools::ExpandListArgument(val, files);
  1124. for ( cc = 0; cc < files.size(); cc ++ )
  1125. {
  1126. files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
  1127. if ( cc > 0 )
  1128. {
  1129. nvalue += ";";
  1130. }
  1131. nvalue += files[cc];
  1132. }
  1133. this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
  1134. val = it.GetValue();
  1135. }
  1136. }
  1137. this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
  1138. // if there was a definition then remove it
  1139. this->Definitions.erase( DefinitionMap::key_type(name));
  1140. }
  1141. void cmMakefile::AddDefinition(const char* name, bool value)
  1142. {
  1143. if(value)
  1144. {
  1145. this->Definitions.erase( DefinitionMap::key_type(name));
  1146. this->Definitions.insert(DefinitionMap::value_type(name, "ON"));
  1147. }
  1148. else
  1149. {
  1150. this->Definitions.erase( DefinitionMap::key_type(name));
  1151. this->Definitions.insert(DefinitionMap::value_type(name, "OFF"));
  1152. }
  1153. #ifdef CMAKE_BUILD_WITH_CMAKE
  1154. cmVariableWatch* vv = this->GetVariableWatch();
  1155. if ( vv )
  1156. {
  1157. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
  1158. value?"ON":"OFF", this);
  1159. }
  1160. #endif
  1161. }
  1162. void cmMakefile::AddCacheDefinition(const char* name,
  1163. bool value,
  1164. const char* doc)
  1165. {
  1166. bool val = value;
  1167. cmCacheManager::CacheIterator it =
  1168. this->GetCacheManager()->GetCacheIterator(name);
  1169. if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
  1170. it.Initialized())
  1171. {
  1172. val = it.GetValueAsBool();
  1173. }
  1174. this->GetCacheManager()->AddCacheEntry(name, val, doc);
  1175. this->AddDefinition(name, val);
  1176. }
  1177. void cmMakefile::RemoveDefinition(const char* name)
  1178. {
  1179. this->Definitions.erase(DefinitionMap::key_type(name));
  1180. #ifdef CMAKE_BUILD_WITH_CMAKE
  1181. cmVariableWatch* vv = this->GetVariableWatch();
  1182. if ( vv )
  1183. {
  1184. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
  1185. 0, this);
  1186. }
  1187. #endif
  1188. }
  1189. void cmMakefile::SetProjectName(const char* p)
  1190. {
  1191. this->ProjectName = p;
  1192. }
  1193. void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
  1194. {
  1195. // for these targets do not add anything
  1196. switch(target.GetType())
  1197. {
  1198. case cmTarget::UTILITY:
  1199. case cmTarget::GLOBAL_TARGET:
  1200. return;
  1201. default:;
  1202. }
  1203. std::vector<std::string>::iterator j;
  1204. for(j = this->LinkDirectories.begin();
  1205. j != this->LinkDirectories.end(); ++j)
  1206. {
  1207. target.AddLinkDirectory(j->c_str());
  1208. }
  1209. target.MergeLinkLibraries( *this, name, this->LinkLibraries );
  1210. }
  1211. void cmMakefile::AddLibrary(const char* lname, int shared,
  1212. const std::vector<std::string> &srcs,
  1213. bool excludeFromAll)
  1214. {
  1215. cmTarget* target=0;
  1216. switch (shared)
  1217. {
  1218. case 0:
  1219. target=this->AddNewTarget(cmTarget::STATIC_LIBRARY, lname, false);
  1220. break;
  1221. case 1:
  1222. target=this->AddNewTarget(cmTarget::SHARED_LIBRARY, lname, false);
  1223. break;
  1224. case 2:
  1225. target=this->AddNewTarget(cmTarget::MODULE_LIBRARY, lname, false);
  1226. break;
  1227. default:
  1228. target=this->AddNewTarget(cmTarget::STATIC_LIBRARY, lname, false);
  1229. }
  1230. // Clear its dependencies. Otherwise, dependencies might persist
  1231. // over changes in CMakeLists.txt, making the information stale and
  1232. // hence useless.
  1233. target->ClearDependencyInformation( *this, lname );
  1234. if(excludeFromAll)
  1235. {
  1236. target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
  1237. }
  1238. target->SetSourceList(srcs);
  1239. this->AddGlobalLinkInformation(lname, *target);
  1240. }
  1241. cmTarget* cmMakefile::AddExecutable(const char *exeName,
  1242. const std::vector<std::string> &srcs,
  1243. bool excludeFromAll)
  1244. {
  1245. cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName, false);
  1246. if(excludeFromAll)
  1247. {
  1248. target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
  1249. }
  1250. target->SetSourceList(srcs);
  1251. this->AddGlobalLinkInformation(exeName, *target);
  1252. return target;
  1253. }
  1254. cmTarget* cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name, bool isImported)
  1255. {
  1256. cmTargets::iterator it;
  1257. cmTarget target;
  1258. target.SetType(type, name);
  1259. target.SetMakefile(this);
  1260. if (isImported)
  1261. {
  1262. target.MarkAsImported();
  1263. it=this->ImportedTargets.insert(cmTargets::value_type(target.GetName(), target)).first;
  1264. }
  1265. else
  1266. {
  1267. it=this->Targets.insert(cmTargets::value_type(target.GetName(), target)).first;
  1268. }
  1269. this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
  1270. return &it->second;
  1271. }
  1272. cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
  1273. {
  1274. std::string name = cname;
  1275. std::string out;
  1276. // look through all the source files that have custom commands
  1277. // and see if the custom command has the passed source file as an output
  1278. // keep in mind the possible .rule extension that may be tacked on
  1279. for(std::vector<cmSourceFile*>::const_iterator i =
  1280. this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
  1281. {
  1282. // does this source file have a custom command?
  1283. if ((*i)->GetCustomCommand())
  1284. {
  1285. // is the output of the custom command match the source files name
  1286. const std::vector<std::string>& outputs =
  1287. (*i)->GetCustomCommand()->GetOutputs();
  1288. for(std::vector<std::string>::const_iterator o = outputs.begin();
  1289. o != outputs.end(); ++o)
  1290. {
  1291. out = *o;
  1292. std::string::size_type pos = out.rfind(name);
  1293. // If the output matches exactly
  1294. if (pos != out.npos &&
  1295. pos == out.size() - name.size() &&
  1296. (pos ==0 || out[pos-1] == '/'))
  1297. {
  1298. return *i;
  1299. }
  1300. }
  1301. }
  1302. }
  1303. // otherwise return NULL
  1304. return 0;
  1305. }
  1306. #if defined(CMAKE_BUILD_WITH_CMAKE)
  1307. cmSourceGroup* cmMakefile::GetSourceGroup(const char* name)
  1308. {
  1309. // First see if the group exists. If so, replace its regular expression.
  1310. for(std::vector<cmSourceGroup>::iterator sg = this->SourceGroups.begin();
  1311. sg != this->SourceGroups.end(); ++sg)
  1312. {
  1313. std::string sgName = sg->GetName();
  1314. if(sgName == name)
  1315. {
  1316. return &(*sg);
  1317. }
  1318. else
  1319. {
  1320. cmSourceGroup *target = sg->lookupChild(name);
  1321. if(target)
  1322. {
  1323. return target;
  1324. }
  1325. }
  1326. }
  1327. return 0;
  1328. }
  1329. void cmMakefile::AddSourceGroup(const char* name,
  1330. const char* regex,
  1331. const char *parent)
  1332. {
  1333. // First see if the group exists. If so, replace its regular expression.
  1334. for(unsigned int i=0;i<this->SourceGroups.size();++i)
  1335. {
  1336. cmSourceGroup *sg = &this->SourceGroups[i];
  1337. std::string sgName = sg->GetName();
  1338. if(!parent)
  1339. {
  1340. if(sgName == name)
  1341. {
  1342. if ( regex )
  1343. {
  1344. // We only want to set the regular expression. If there are already
  1345. // source files in the group, we don't want to remove them.
  1346. sg->SetGroupRegex(regex);
  1347. }
  1348. return;
  1349. }
  1350. }
  1351. else
  1352. {
  1353. if(sgName == parent)
  1354. {
  1355. cmSourceGroup *localtarget = sg->lookupChild(name);
  1356. if(localtarget)
  1357. {
  1358. if ( regex )
  1359. {
  1360. // We only want to set the regular expression. If there are
  1361. // already source files in the group, we don't want to remove
  1362. // them.
  1363. localtarget->SetGroupRegex(regex);
  1364. }
  1365. }
  1366. else
  1367. {
  1368. sg->AddChild(cmSourceGroup(name, regex));
  1369. }
  1370. return;
  1371. }
  1372. else
  1373. {
  1374. cmSourceGroup *localtarget = sg->lookupChild(parent);
  1375. if(localtarget)
  1376. {
  1377. cmSourceGroup *addtarget = localtarget->lookupChild(name);
  1378. if(addtarget)
  1379. {
  1380. if ( regex )
  1381. {
  1382. // We only want to set the regular expression. If there are
  1383. // already source files in the group, we don't want to
  1384. // remove them.
  1385. addtarget->SetGroupRegex(regex);
  1386. }
  1387. }
  1388. else
  1389. {
  1390. localtarget->AddChild(cmSourceGroup(name, regex));
  1391. }
  1392. return;
  1393. }
  1394. }
  1395. }
  1396. }
  1397. // The group doesn't exist. Add it.
  1398. this->SourceGroups.push_back(cmSourceGroup(name, regex));
  1399. }
  1400. #endif
  1401. void cmMakefile::AddExtraDirectory(const char* dir)
  1402. {
  1403. this->AuxSourceDirectories.push_back(dir);
  1404. }
  1405. // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
  1406. // include and library directories.
  1407. void cmMakefile::ExpandVariables()
  1408. {
  1409. // Now expand variables in the include and link strings
  1410. for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin();
  1411. d != this->IncludeDirectories.end(); ++d)
  1412. {
  1413. this->ExpandVariablesInString(*d, true, true);
  1414. }
  1415. for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
  1416. d != this->LinkDirectories.end(); ++d)
  1417. {
  1418. this->ExpandVariablesInString(*d, true, true);
  1419. }
  1420. for(cmTarget::LinkLibraryVectorType::iterator l =
  1421. this->LinkLibraries.begin();
  1422. l != this->LinkLibraries.end(); ++l)
  1423. {
  1424. this->ExpandVariablesInString(l->first, true, true);
  1425. }
  1426. }
  1427. bool cmMakefile::IsOn(const char* name) const
  1428. {
  1429. const char* value = this->GetDefinition(name);
  1430. return cmSystemTools::IsOn(value);
  1431. }
  1432. bool cmMakefile::IsSet(const char* name) const
  1433. {
  1434. const char* value = this->GetDefinition(name);
  1435. if ( !value )
  1436. {
  1437. return false;
  1438. }
  1439. if ( ! *value )
  1440. {
  1441. return false;
  1442. }
  1443. if ( cmSystemTools::IsNOTFOUND(value) )
  1444. {
  1445. return false;
  1446. }
  1447. return true;
  1448. }
  1449. bool cmMakefile::CanIWriteThisFile(const char* fileName)
  1450. {
  1451. if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
  1452. {
  1453. return true;
  1454. }
  1455. // If we are doing an in-source build, than the test will always fail
  1456. if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
  1457. this->GetHomeOutputDirectory()) )
  1458. {
  1459. if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
  1460. {
  1461. return false;
  1462. }
  1463. return true;
  1464. }
  1465. // Check if this is subdirectory of the source tree but not a
  1466. // subdirectory of a build tree
  1467. if ( cmSystemTools::IsSubDirectory(fileName,
  1468. this->GetHomeDirectory()) &&
  1469. !cmSystemTools::IsSubDirectory(fileName,
  1470. this->GetHomeOutputDirectory()) )
  1471. {
  1472. return false;
  1473. }
  1474. return true;
  1475. }
  1476. const char* cmMakefile::GetRequiredDefinition(const char* name) const
  1477. {
  1478. const char* ret = this->GetDefinition(name);
  1479. if(!ret)
  1480. {
  1481. cmSystemTools::Error("Error required internal CMake variable not "
  1482. "set, cmake may be not be built correctly.\n",
  1483. "Missing variable is:\n",
  1484. name);
  1485. return "";
  1486. }
  1487. return ret;
  1488. }
  1489. bool cmMakefile::IsDefinitionSet(const char* name) const
  1490. {
  1491. const char* def = 0;
  1492. DefinitionMap::const_iterator pos = this->Definitions.find(name);
  1493. if(pos != this->Definitions.end())
  1494. {
  1495. def = (*pos).second.c_str();
  1496. }
  1497. else
  1498. {
  1499. def = this->GetCacheManager()->GetCacheValue(name);
  1500. }
  1501. #ifdef CMAKE_BUILD_WITH_CMAKE
  1502. if(cmVariableWatch* vv = this->GetVariableWatch())
  1503. {
  1504. if(!def)
  1505. {
  1506. vv->VariableAccessed
  1507. (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
  1508. def, this);
  1509. }
  1510. }
  1511. #endif
  1512. return def?true:false;
  1513. }
  1514. const char* cmMakefile::GetDefinition(const char* name) const
  1515. {
  1516. const char* def = 0;
  1517. DefinitionMap::const_iterator pos = this->Definitions.find(name);
  1518. if(pos != this->Definitions.end())
  1519. {
  1520. def = (*pos).second.c_str();
  1521. }
  1522. else
  1523. {
  1524. def = this->GetCacheManager()->GetCacheValue(name);
  1525. }
  1526. #ifdef CMAKE_BUILD_WITH_CMAKE
  1527. cmVariableWatch* vv = this->GetVariableWatch();
  1528. if ( vv )
  1529. {
  1530. if ( def )
  1531. {
  1532. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
  1533. def, this);
  1534. }
  1535. else
  1536. {
  1537. // are unknown access allowed
  1538. DefinitionMap::const_iterator pos2 =
  1539. this->Definitions.find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
  1540. if (pos2 != this->Definitions.end() &&
  1541. cmSystemTools::IsOn((*pos2).second.c_str()))
  1542. {
  1543. vv->VariableAccessed(name,
  1544. cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
  1545. }
  1546. else
  1547. {
  1548. vv->VariableAccessed(name,
  1549. cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
  1550. }
  1551. }
  1552. }
  1553. #endif
  1554. return def;
  1555. }
  1556. const char* cmMakefile::GetSafeDefinition(const char* def) const
  1557. {
  1558. const char* ret = this->GetDefinition(def);
  1559. if(!ret)
  1560. {
  1561. return "";
  1562. }
  1563. return ret;
  1564. }
  1565. std::vector<std::string> cmMakefile
  1566. ::GetDefinitions(int cacheonly /* = 0 */) const
  1567. {
  1568. std::map<cmStdString, int> definitions;
  1569. if ( !cacheonly )
  1570. {
  1571. DefinitionMap::const_iterator it;
  1572. for ( it = this->Definitions.begin();
  1573. it != this->Definitions.end(); it ++ )
  1574. {
  1575. definitions[it->first] = 1;
  1576. }
  1577. }
  1578. cmCacheManager::CacheIterator cit =
  1579. this->GetCacheManager()->GetCacheIterator();
  1580. for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
  1581. {
  1582. definitions[cit.GetName()] = 1;
  1583. }
  1584. std::vector<std::string> res;
  1585. std::map<cmStdString, int>::iterator fit;
  1586. for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
  1587. {
  1588. res.push_back(fit->first);
  1589. }
  1590. return res;
  1591. }
  1592. const char *cmMakefile::ExpandVariablesInString(std::string& source)
  1593. {
  1594. return this->ExpandVariablesInString(source, false, false);
  1595. }
  1596. const char *cmMakefile::ExpandVariablesInString(std::string& source,
  1597. bool escapeQuotes,
  1598. bool noEscapes,
  1599. bool atOnly,
  1600. const char* filename,
  1601. long line,
  1602. bool removeEmpty,
  1603. bool replaceAt)
  1604. {
  1605. if ( source.empty() || source.find_first_of("$@\\") == source.npos)
  1606. {
  1607. return source.c_str();
  1608. }
  1609. // Special-case the @ONLY mode.
  1610. if(atOnly)
  1611. {
  1612. if(!noEscapes || !removeEmpty || !replaceAt)
  1613. {
  1614. // This case should never be called. At-only is for
  1615. // configure-file/string which always does no escapes.
  1616. abort();
  1617. }
  1618. // Store an original copy of the input.
  1619. std::string input = source;
  1620. // Start with empty output.
  1621. source = "";
  1622. // Look for one @VAR@ at a time.
  1623. const char* in = input.c_str();
  1624. while(this->cmAtVarRegex.find(in))
  1625. {
  1626. // Get the range of the string to replace.
  1627. const char* first = in + this->cmAtVarRegex.start();
  1628. const char* last = in + this->cmAtVarRegex.end();
  1629. // Store the unchanged part of the string now.
  1630. source.append(in, first-in);
  1631. // Lookup the definition of VAR.
  1632. std::string var(first+1, last-first-2);
  1633. if(const char* val = this->GetDefinition(var.c_str()))
  1634. {
  1635. // Store the value in the output escaping as requested.
  1636. if(escapeQuotes)
  1637. {
  1638. source.append(cmSystemTools::EscapeQuotes(val));
  1639. }
  1640. else
  1641. {
  1642. source.append(val);
  1643. }
  1644. }
  1645. // Continue looking for @VAR@ further along the string.
  1646. in = last;
  1647. }
  1648. // Append the rest of the unchanged part of the string.
  1649. source.append(in);
  1650. return source.c_str();
  1651. }
  1652. // This method replaces ${VAR} and @VAR@ where VAR is looked up
  1653. // with GetDefinition(), if not found in the map, nothing is expanded.
  1654. // It also supports the $ENV{VAR} syntax where VAR is looked up in
  1655. // the current environment variables.
  1656. cmCommandArgumentParserHelper parser;
  1657. parser.SetMakefile(this);
  1658. parser.SetLineFile(line, filename);
  1659. parser.SetEscapeQuotes(escapeQuotes);
  1660. parser.SetNoEscapeMode(noEscapes);
  1661. parser.SetReplaceAtSyntax(replaceAt);
  1662. parser.SetRemoveEmpty(removeEmpty);
  1663. int res = parser.ParseString(source.c_str(), 0);
  1664. if ( res )
  1665. {
  1666. source = parser.GetResult();
  1667. }
  1668. else
  1669. {
  1670. cmOStringStream error;
  1671. error << "Syntax error in cmake code at\n"
  1672. << (filename?filename:"(no filename given)")
  1673. << ":" << line << ":\n"
  1674. << parser.GetError() << ", when parsing string \""
  1675. << source.c_str() << "\"";
  1676. const char* versionValue
  1677. = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
  1678. int major = 0;
  1679. int minor = 0;
  1680. if ( versionValue )
  1681. {
  1682. sscanf(versionValue, "%d.%d", &major, &minor);
  1683. }
  1684. if ( major < 2 || major == 2 && minor < 1 )
  1685. {
  1686. cmSystemTools::Error(error.str().c_str());
  1687. cmSystemTools::SetFatalErrorOccured();
  1688. return source.c_str();
  1689. }
  1690. else
  1691. {
  1692. cmSystemTools::Message(error.str().c_str());
  1693. }
  1694. }
  1695. return source.c_str();
  1696. }
  1697. void cmMakefile::RemoveVariablesInString(std::string& source,
  1698. bool atOnly) const
  1699. {
  1700. if(!atOnly)
  1701. {
  1702. cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
  1703. while (var.find(source))
  1704. {
  1705. source.erase(var.start(),var.end() - var.start());
  1706. }
  1707. }
  1708. if(!atOnly)
  1709. {
  1710. cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
  1711. while (varb.find(source))
  1712. {
  1713. source.erase(varb.start(),varb.end() - varb.start());
  1714. }
  1715. }
  1716. cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
  1717. while (var2.find(source))
  1718. {
  1719. source.erase(var2.start(),var2.end() - var2.start());
  1720. }
  1721. }
  1722. /**
  1723. * Add the default definitions to the makefile. These values must not
  1724. * be dependent on anything that isn't known when this cmMakefile instance
  1725. * is constructed.
  1726. */
  1727. void cmMakefile::AddDefaultDefinitions()
  1728. {
  1729. #if defined(_WIN32) || defined(__CYGWIN__)
  1730. this->AddDefinition("WIN32", "1");
  1731. #else
  1732. this->AddDefinition("UNIX", "1");
  1733. #endif
  1734. // Cygwin is more like unix so enable the unix commands
  1735. #if defined(__CYGWIN__)
  1736. this->AddDefinition("UNIX", "1");
  1737. this->AddDefinition("CYGWIN", "1");
  1738. #endif
  1739. #if defined(__APPLE__)
  1740. this->AddDefinition("APPLE", "1");
  1741. #endif
  1742. #if defined(__QNXNTO__)
  1743. this->AddDefinition("QNXNTO", "1");
  1744. #endif
  1745. #if defined(__BEOS__)
  1746. this->AddDefinition("BEOS", "1");
  1747. #endif
  1748. char temp[1024];
  1749. sprintf(temp, "%d", cmVersion::GetMinorVersion());
  1750. this->AddDefinition("CMAKE_MINOR_VERSION", temp);
  1751. sprintf(temp, "%d", cmVersion::GetMajorVersion());
  1752. this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
  1753. sprintf(temp, "%d", cmVersion::GetPatchVersion());
  1754. this->AddDefinition("CMAKE_PATCH_VERSION", temp);
  1755. this->AddDefinition("CMAKE_FILES_DIRECTORY",
  1756. cmake::GetCMakeFilesDirectory());
  1757. }
  1758. #if defined(CMAKE_BUILD_WITH_CMAKE)
  1759. /**
  1760. * Find a source group whose regular expression matches the filename
  1761. * part of the given source name. Search backward through the list of
  1762. * source groups, and take the first matching group found. This way
  1763. * non-inherited SOURCE_GROUP commands will have precedence over
  1764. * inherited ones.
  1765. */
  1766. cmSourceGroup&
  1767. cmMakefile::FindSourceGroup(const char* source,
  1768. std::vector<cmSourceGroup> &groups)
  1769. {
  1770. // First search for a group that lists the file explicitly.
  1771. for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
  1772. sg != groups.rend(); ++sg)
  1773. {
  1774. cmSourceGroup *result = sg->MatchChildrenFiles(source);
  1775. if(result)
  1776. {
  1777. return *result;
  1778. }
  1779. }
  1780. // Now search for a group whose regex matches the file.
  1781. for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
  1782. sg != groups.rend(); ++sg)
  1783. {
  1784. cmSourceGroup *result = sg->MatchChildrenRegex(source);
  1785. if(result)
  1786. {
  1787. return *result;
  1788. }
  1789. }
  1790. // Shouldn't get here, but just in case, return the default group.
  1791. return groups.front();
  1792. }
  1793. #endif
  1794. bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff)
  1795. {
  1796. // if there are no blockers get out of here
  1797. if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
  1798. {
  1799. return false;
  1800. }
  1801. // loop over all function blockers to see if any block this command
  1802. // evaluate in reverse, this is critical for balanced IF statements etc
  1803. std::list<cmFunctionBlocker *>::reverse_iterator pos;
  1804. for (pos = this->FunctionBlockers.rbegin();
  1805. pos != this->FunctionBlockers.rend(); ++pos)
  1806. {
  1807. if((*pos)->IsFunctionBlocked(lff, *this))
  1808. {
  1809. return true;
  1810. }
  1811. }
  1812. return false;
  1813. }
  1814. void cmMakefile::ExpandArguments(
  1815. std::vector<cmListFileArgument> const& inArgs,
  1816. std::vector<std::string>& outArgs)
  1817. {
  1818. std::vector<cmListFileArgument>::const_iterator i;
  1819. std::string value;
  1820. outArgs.reserve(inArgs.size());
  1821. for(i = inArgs.begin(); i != inArgs.end(); ++i)
  1822. {
  1823. // Expand the variables in the argument.
  1824. value = i->Value;
  1825. this->ExpandVariablesInString(value, false, false, false,
  1826. i->FilePath, i->Line,
  1827. false, true);
  1828. // If the argument is quoted, it should be one argument.
  1829. // Otherwise, it may be a list of arguments.
  1830. if(i->Quoted)
  1831. {
  1832. outArgs.push_back(value);
  1833. }
  1834. else
  1835. {
  1836. cmSystemTools::ExpandListArgument(value, outArgs);
  1837. }
  1838. }
  1839. }
  1840. void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
  1841. {
  1842. // loop over all function blockers to see if any block this command
  1843. std::list<cmFunctionBlocker *>::reverse_iterator pos;
  1844. for (pos = this->FunctionBlockers.rbegin();
  1845. pos != this->FunctionBlockers.rend(); ++pos)
  1846. {
  1847. if ((*pos)->ShouldRemove(lff, *this))
  1848. {
  1849. cmFunctionBlocker* b = *pos;
  1850. this->FunctionBlockers.remove(b);
  1851. delete b;
  1852. break;
  1853. }
  1854. }
  1855. return;
  1856. }
  1857. void cmMakefile::SetHomeDirectory(const char* dir)
  1858. {
  1859. this->cmHomeDirectory = dir;
  1860. cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
  1861. this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
  1862. if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
  1863. {
  1864. this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
  1865. }
  1866. }
  1867. void cmMakefile::SetHomeOutputDirectory(const char* lib)
  1868. {
  1869. this->HomeOutputDirectory = lib;
  1870. cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
  1871. this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
  1872. if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
  1873. {
  1874. this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
  1875. this->GetHomeOutputDirectory());
  1876. }
  1877. }
  1878. /**
  1879. * Register the given cmData instance with its own name.
  1880. */
  1881. void cmMakefile::RegisterData(cmData* data)
  1882. {
  1883. std::string name = data->GetName();
  1884. DataMapType::const_iterator d = this->DataMap.find(name);
  1885. if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
  1886. {
  1887. delete d->second;
  1888. }
  1889. this->DataMap[name] = data;
  1890. }
  1891. /**
  1892. * Register the given cmData instance with the given name. This can be used
  1893. * to register a NULL pointer.
  1894. */
  1895. void cmMakefile::RegisterData(const char* name, cmData* data)
  1896. {
  1897. DataMapType::const_iterator d = this->DataMap.find(name);
  1898. if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
  1899. {
  1900. delete d->second;
  1901. }
  1902. this->DataMap[name] = data;
  1903. }
  1904. /**
  1905. * Lookup a cmData instance previously registered with the given name. If
  1906. * the instance cannot be found, return NULL.
  1907. */
  1908. cmData* cmMakefile::LookupData(const char* name) const
  1909. {
  1910. DataMapType::const_iterator d = this->DataMap.find(name);
  1911. if(d != this->DataMap.end())
  1912. {
  1913. return d->second;
  1914. }
  1915. else
  1916. {
  1917. return 0;
  1918. }
  1919. }
  1920. cmSourceFile* cmMakefile::GetSource(const char* sourceName) const
  1921. {
  1922. // if the source is provided with a full path use it, otherwise
  1923. // by default it is in the current source dir
  1924. std::string path;
  1925. if (cmSystemTools::FileIsFullPath(sourceName))
  1926. {
  1927. path = cmSystemTools::GetFilenamePath(sourceName);
  1928. }
  1929. else
  1930. {
  1931. path = this->GetCurrentDirectory();
  1932. // even though it is not a full path, it may still be relative
  1933. std::string subpath = cmSystemTools::GetFilenamePath(sourceName);
  1934. if (!subpath.empty())
  1935. {
  1936. path += "/";
  1937. path += cmSystemTools::GetFilenamePath(sourceName);
  1938. }
  1939. }
  1940. path = cmSystemTools::CollapseFullPath(path.c_str());
  1941. std::string sname =
  1942. cmSystemTools::GetFilenameWithoutLastExtension(sourceName);
  1943. // compute the extension
  1944. std::string ext
  1945. = cmSystemTools::GetFilenameLastExtension(sourceName);
  1946. if ( ext.length() && ext[0] == '.' )
  1947. {
  1948. ext = ext.substr(1);
  1949. }
  1950. for(std::vector<cmSourceFile*>::const_iterator i =
  1951. this->SourceFiles.begin();
  1952. i != this->SourceFiles.end(); ++i)
  1953. {
  1954. if ((*i)->GetSourceNameWithoutLastExtension() == sname &&
  1955. cmSystemTools::GetFilenamePath((*i)->GetFullPath()) == path &&
  1956. (ext.size() == 0 || (ext == (*i)->GetSourceExtension())))
  1957. {
  1958. return *i;
  1959. }
  1960. }
  1961. // geeze, if it wasn't found maybe it is listed under the output dir
  1962. if (!cmSystemTools::GetFilenamePath(sourceName).empty())
  1963. {
  1964. return 0;
  1965. }
  1966. path = this->GetCurrentOutputDirectory();
  1967. for(std::vector<cmSourceFile*>::const_iterator i =
  1968. this->SourceFiles.begin();
  1969. i != this->SourceFiles.end(); ++i)
  1970. {
  1971. if ((*i)->GetSourceName() == sname &&
  1972. cmSystemTools::GetFilenamePath((*i)->GetFullPath()) == path &&
  1973. (ext.size() == 0 || (ext == (*i)->GetSourceExtension())))
  1974. {
  1975. return *i;
  1976. }
  1977. }
  1978. return 0;
  1979. }
  1980. cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
  1981. bool generated)
  1982. {
  1983. // make it a full path first
  1984. std::string src = sourceName;
  1985. bool relative = !cmSystemTools::FileIsFullPath(sourceName);
  1986. std::string srcTreeFile = this->GetCurrentDirectory();
  1987. srcTreeFile += "/";
  1988. srcTreeFile += sourceName;
  1989. if(relative)
  1990. {
  1991. src = srcTreeFile;
  1992. }
  1993. // check to see if it exists
  1994. cmSourceFile* ret = this->GetSource(src.c_str());
  1995. if (ret)
  1996. {
  1997. return ret;
  1998. }
  1999. // OK a source file object doesn't exist for the source
  2000. // maybe we made a bad call on assuming it was in the src tree
  2001. std::string buildTreeFile = this->GetCurrentOutputDirectory();
  2002. buildTreeFile += "/";
  2003. buildTreeFile += sourceName;
  2004. if (relative)
  2005. {
  2006. src = buildTreeFile;
  2007. ret = this->GetSource(src.c_str());
  2008. if (ret)
  2009. {
  2010. return ret;
  2011. }
  2012. // if it has not been marked generated check to see if it exists in the
  2013. // src tree
  2014. if(!generated)
  2015. {
  2016. // see if the file is in the source tree, otherwise assume it
  2017. // is in the binary tree
  2018. if (cmSystemTools::FileExists(srcTreeFile.c_str()) &&
  2019. !cmSystemTools::FileIsDirectory(srcTreeFile.c_str()))
  2020. {
  2021. src = srcTreeFile;
  2022. }
  2023. else
  2024. {
  2025. if ( cmSystemTools::GetFilenameLastExtension
  2026. (srcTreeFile.c_str()).size() == 0)
  2027. {
  2028. if (cmSystemTools::DoesFileExistWithExtensions(
  2029. srcTreeFile.c_str(), this->GetSourceExtensions()))
  2030. {
  2031. src = srcTreeFile;
  2032. }
  2033. else if (cmSystemTools::DoesFileExistWithExtensions(
  2034. srcTreeFile.c_str(), this->GetHeaderExtensions()))
  2035. {
  2036. src = srcTreeFile;
  2037. }
  2038. }
  2039. }
  2040. }
  2041. }
  2042. // a cmSourceFile instance does not exist yet so we must create one
  2043. // go back to looking in the source directory for it
  2044. // we must create one
  2045. cmSourceFile file;
  2046. file.SetMakefile(this);
  2047. std::string path = cmSystemTools::GetFilenamePath(src);
  2048. if(generated)
  2049. {
  2050. std::string ext = cmSystemTools::GetFilenameLastExtension(src);
  2051. std::string name_no_ext = cmSystemTools::GetFilenameName(src.c_str());
  2052. name_no_ext = name_no_ext.substr(0, name_no_ext.length()-ext.length());
  2053. if ( ext.length() && ext[0] == '.' )
  2054. {
  2055. ext = ext.substr(1);
  2056. }
  2057. bool headerFile =
  2058. !(std::find( this->HeaderFileExtensions.begin(),
  2059. this->HeaderFileExtensions.end(), ext ) ==
  2060. this->HeaderFileExtensions.end());
  2061. file.SetName(name_no_ext.c_str(), path.c_str(), ext.c_str(), headerFile);
  2062. }
  2063. else
  2064. {
  2065. std::string relPath = cmSystemTools::GetFilenamePath(sourceName);
  2066. if (relative && relPath.size())
  2067. {
  2068. // we need to keep the relative part of the filename
  2069. std::string fullPathLessRel = path;
  2070. std::string::size_type pos = fullPathLessRel.rfind(relPath);
  2071. if (pos == std::string::npos)
  2072. {
  2073. cmSystemTools::Error(
  2074. "CMake failed to properly look up relative cmSourceFile: ",
  2075. sourceName);
  2076. }
  2077. fullPathLessRel.erase(pos-1);
  2078. file.SetName(sourceName, fullPathLessRel.c_str(),
  2079. this->GetSourceExtensions(),
  2080. this->GetHeaderExtensions());
  2081. }
  2082. else
  2083. {
  2084. file.SetName(cmSystemTools::GetFilenameName(src.c_str()).c_str(),
  2085. path.c_str(),
  2086. this->GetSourceExtensions(),
  2087. this->GetHeaderExtensions());
  2088. }
  2089. }
  2090. // add the source file to the makefile
  2091. this->AddSource(file);
  2092. src = file.GetFullPath();
  2093. ret = this->GetSource(src.c_str());
  2094. if (!ret)
  2095. {
  2096. cmSystemTools::Error(
  2097. "CMake failed to properly look up cmSourceFile: ", sourceName);
  2098. }
  2099. else
  2100. {
  2101. ret->SetMakefile(this);
  2102. }
  2103. return ret;
  2104. }
  2105. cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
  2106. {
  2107. // check to see if it exists
  2108. cmSourceFile* ret = this->GetSource(sf.GetFullPath().c_str());
  2109. if(ret)
  2110. {
  2111. return ret;
  2112. }
  2113. ret = new cmSourceFile(sf);
  2114. this->SourceFiles.push_back(ret);
  2115. return ret;
  2116. }
  2117. void cmMakefile::EnableLanguage(std::vector<std::string> const & lang)
  2118. {
  2119. this->AddDefinition("CMAKE_CFG_INTDIR",
  2120. this->LocalGenerator->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
  2121. this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this);
  2122. }
  2123. void cmMakefile::ExpandSourceListArguments(
  2124. std::vector<std::string> const& arguments,
  2125. std::vector<std::string>& newargs, unsigned int /* start */)
  2126. {
  2127. // now expand the args
  2128. unsigned int i;
  2129. for(i = 0; i < arguments.size(); ++i)
  2130. {
  2131. // List expansion will have been done already.
  2132. newargs.push_back(arguments[i]);
  2133. }
  2134. }
  2135. int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
  2136. const char *projectName, const char *targetName,
  2137. const std::vector<std::string> *cmakeArgs,
  2138. std::string *output)
  2139. {
  2140. // does the binary directory exist ? If not create it...
  2141. if (!cmSystemTools::FileIsDirectory(bindir))
  2142. {
  2143. cmSystemTools::MakeDirectory(bindir);
  2144. }
  2145. // change to the tests directory and run cmake
  2146. // use the cmake object instead of calling cmake
  2147. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  2148. cmSystemTools::ChangeDirectory(bindir);
  2149. // make sure the same generator is used
  2150. // use this program as the cmake to be run, it should not
  2151. // be run that way but the cmake object requires a vailid path
  2152. std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
  2153. cmake cm;
  2154. cm.SetIsInTryCompile(true);
  2155. cmGlobalGenerator *gg = cm.CreateGlobalGenerator
  2156. (this->LocalGenerator->GetGlobalGenerator()->GetName());
  2157. if (!gg)
  2158. {
  2159. cmSystemTools::Error(
  2160. "Internal CMake error, TryCompile bad GlobalGenerator");
  2161. // return to the original directory
  2162. cmSystemTools::ChangeDirectory(cwd.c_str());
  2163. return 1;
  2164. }
  2165. cm.SetGlobalGenerator(gg);
  2166. // do a configure
  2167. cm.SetHomeDirectory(srcdir);
  2168. cm.SetHomeOutputDirectory(bindir);
  2169. cm.SetStartDirectory(srcdir);
  2170. cm.SetStartOutputDirectory(bindir);
  2171. cm.SetCMakeCommand(cmakeCommand.c_str());
  2172. cm.LoadCache();
  2173. // if cmake args were provided then pass them in
  2174. if (cmakeArgs)
  2175. {
  2176. cm.SetCacheArgs(*cmakeArgs);
  2177. }
  2178. // to save time we pass the EnableLanguage info directly
  2179. gg->EnableLanguagesFromGenerator
  2180. (this->LocalGenerator->GetGlobalGenerator());
  2181. if (cm.Configure() != 0)
  2182. {
  2183. cmSystemTools::Error(
  2184. "Internal CMake error, TryCompile configure of cmake failed");
  2185. // return to the original directory
  2186. cmSystemTools::ChangeDirectory(cwd.c_str());
  2187. return 1;
  2188. }
  2189. if (cm.Generate() != 0)
  2190. {
  2191. cmSystemTools::Error(
  2192. "Internal CMake error, TryCompile generation of cmake failed");
  2193. // return to the original directory
  2194. cmSystemTools::ChangeDirectory(cwd.c_str());
  2195. return 1;
  2196. }
  2197. // finally call the generator to actually build the resulting project
  2198. int ret =
  2199. this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
  2200. projectName,
  2201. targetName,
  2202. output,
  2203. this);
  2204. cmSystemTools::ChangeDirectory(cwd.c_str());
  2205. return ret;
  2206. }
  2207. cmake *cmMakefile::GetCMakeInstance() const
  2208. {
  2209. if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
  2210. {
  2211. return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
  2212. }
  2213. return 0;
  2214. }
  2215. #ifdef CMAKE_BUILD_WITH_CMAKE
  2216. cmVariableWatch *cmMakefile::GetVariableWatch() const
  2217. {
  2218. if ( this->GetCMakeInstance() &&
  2219. this->GetCMakeInstance()->GetVariableWatch() )
  2220. {
  2221. return this->GetCMakeInstance()->GetVariableWatch();
  2222. }
  2223. return 0;
  2224. }
  2225. #endif
  2226. void cmMakefile::AddMacro(const char* name, const char* signature)
  2227. {
  2228. if ( !name || !signature )
  2229. {
  2230. return;
  2231. }
  2232. this->MacrosMap[name] = signature;
  2233. }
  2234. void cmMakefile::GetListOfMacros(std::string& macros)
  2235. {
  2236. StringStringMap::iterator it;
  2237. macros = "";
  2238. int cc = 0;
  2239. for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
  2240. {
  2241. if ( cc > 0 )
  2242. {
  2243. macros += ";";
  2244. }
  2245. macros += it->first;
  2246. cc ++;
  2247. }
  2248. }
  2249. cmCacheManager *cmMakefile::GetCacheManager() const
  2250. {
  2251. return this->GetCMakeInstance()->GetCacheManager();
  2252. }
  2253. void cmMakefile::DisplayStatus(const char* message, float s)
  2254. {
  2255. this->GetLocalGenerator()->GetGlobalGenerator()
  2256. ->GetCMakeInstance()->UpdateProgress(message, s);
  2257. }
  2258. std::string cmMakefile::GetModulesFile(const char* filename)
  2259. {
  2260. std::vector<std::string> modulePath;
  2261. const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
  2262. if(def)
  2263. {
  2264. cmSystemTools::ExpandListArgument(def, modulePath);
  2265. }
  2266. // Also search in the standard modules location.
  2267. def = this->GetDefinition("CMAKE_ROOT");
  2268. if(def)
  2269. {
  2270. std::string rootModules = def;
  2271. rootModules += "/Modules";
  2272. modulePath.push_back(rootModules);
  2273. }
  2274. //std::string Look through the possible module directories.
  2275. for(std::vector<std::string>::iterator i = modulePath.begin();
  2276. i != modulePath.end(); ++i)
  2277. {
  2278. std::string itempl = *i;
  2279. cmSystemTools::ConvertToUnixSlashes(itempl);
  2280. itempl += "/";
  2281. itempl += filename;
  2282. if(cmSystemTools::FileExists(itempl.c_str()))
  2283. {
  2284. return itempl;
  2285. }
  2286. }
  2287. return "";
  2288. }
  2289. void cmMakefile::ConfigureString(const std::string& input,
  2290. std::string& output, bool atOnly,
  2291. bool escapeQuotes)
  2292. {
  2293. // Split input to handle one line at a time.
  2294. std::string::const_iterator lineStart = input.begin();
  2295. while(lineStart != input.end())
  2296. {
  2297. // Find the end of this line.
  2298. std::string::const_iterator lineEnd = lineStart;
  2299. while(lineEnd != input.end() && *lineEnd != '\n')
  2300. {
  2301. ++lineEnd;
  2302. }
  2303. // Copy the line.
  2304. std::string line(lineStart, lineEnd);
  2305. // Skip the newline character.
  2306. bool haveNewline = (lineEnd != input.end());
  2307. if(haveNewline)
  2308. {
  2309. ++lineEnd;
  2310. }
  2311. // Replace #cmakedefine instances.
  2312. if(this->cmDefineRegex.find(line))
  2313. {
  2314. const char* def =
  2315. this->GetDefinition(this->cmDefineRegex.match(1).c_str());
  2316. if(!cmSystemTools::IsOff(def))
  2317. {
  2318. cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
  2319. output += line;
  2320. }
  2321. else
  2322. {
  2323. cmSystemTools::ReplaceString(line, "#cmakedefine", "#undef");
  2324. output += "/* ";
  2325. output += line;
  2326. output += " */";
  2327. }
  2328. }
  2329. else if(this->cmDefine01Regex.find(line))
  2330. {
  2331. const char* def =
  2332. this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
  2333. cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
  2334. output += line;
  2335. if(!cmSystemTools::IsOff(def))
  2336. {
  2337. output += " 1";
  2338. }
  2339. else
  2340. {
  2341. output += " 0";
  2342. }
  2343. }
  2344. else
  2345. {
  2346. output += line;
  2347. }
  2348. if(haveNewline)
  2349. {
  2350. output += "\n";
  2351. }
  2352. // Move to the next line.
  2353. lineStart = lineEnd;
  2354. }
  2355. // Perform variable replacements.
  2356. this->ExpandVariablesInString(output, escapeQuotes, true,
  2357. atOnly, 0, -1, true);
  2358. }
  2359. int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
  2360. bool copyonly, bool atOnly, bool escapeQuotes)
  2361. {
  2362. int res = 1;
  2363. if ( !this->CanIWriteThisFile(outfile) )
  2364. {
  2365. cmSystemTools::Error("Attempt to write file: ",
  2366. outfile, " into a source directory.");
  2367. return 0;
  2368. }
  2369. if ( !cmSystemTools::FileExists(infile) )
  2370. {
  2371. cmSystemTools::Error("File ", infile, " does not exist.");
  2372. return 0;
  2373. }
  2374. std::string soutfile = outfile;
  2375. std::string sinfile = infile;
  2376. this->AddCMakeDependFile(infile);
  2377. cmSystemTools::ConvertToUnixSlashes(soutfile);
  2378. mode_t perm = 0;
  2379. cmSystemTools::GetPermissions(sinfile.c_str(), perm);
  2380. std::string::size_type pos = soutfile.rfind('/');
  2381. if(pos != std::string::npos)
  2382. {
  2383. std::string path = soutfile.substr(0, pos);
  2384. cmSystemTools::MakeDirectory(path.c_str());
  2385. }
  2386. if(copyonly)
  2387. {
  2388. if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
  2389. soutfile.c_str()))
  2390. {
  2391. return 0;
  2392. }
  2393. }
  2394. else
  2395. {
  2396. std::string tempOutputFile = soutfile;
  2397. tempOutputFile += ".tmp";
  2398. std::ofstream fout(tempOutputFile.c_str());
  2399. if(!fout)
  2400. {
  2401. cmSystemTools::Error(
  2402. "Could not open file for write in copy operation ",
  2403. tempOutputFile.c_str());
  2404. cmSystemTools::ReportLastSystemError("");
  2405. return 0;
  2406. }
  2407. std::ifstream fin(sinfile.c_str());
  2408. if(!fin)
  2409. {
  2410. cmSystemTools::Error("Could not open file for read in copy operation ",
  2411. sinfile.c_str());
  2412. return 0;
  2413. }
  2414. // now copy input to output and expand variables in the
  2415. // input file at the same time
  2416. std::string inLine;
  2417. std::string outLine;
  2418. while( cmSystemTools::GetLineFromStream(fin, inLine) )
  2419. {
  2420. outLine = "";
  2421. this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
  2422. fout << outLine.c_str() << "\n";
  2423. }
  2424. // close the files before attempting to copy
  2425. fin.close();
  2426. fout.close();
  2427. if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
  2428. soutfile.c_str()) )
  2429. {
  2430. res = 0;
  2431. }
  2432. else
  2433. {
  2434. cmSystemTools::SetPermissions(soutfile.c_str(), perm);
  2435. }
  2436. cmSystemTools::RemoveFile(tempOutputFile.c_str());
  2437. }
  2438. return res;
  2439. }
  2440. void cmMakefile::AddWrittenFile(const char* file)
  2441. { this->GetCMakeInstance()->AddWrittenFile(file); }
  2442. bool cmMakefile::HasWrittenFile(const char* file)
  2443. { return this->GetCMakeInstance()->HasWrittenFile(file); }
  2444. bool cmMakefile::CheckInfiniteLoops()
  2445. {
  2446. std::vector<std::string>::iterator it;
  2447. for ( it = this->ListFiles.begin();
  2448. it != this->ListFiles.end();
  2449. ++ it )
  2450. {
  2451. if ( this->HasWrittenFile(it->c_str()) )
  2452. {
  2453. cmOStringStream str;
  2454. str << "File " << it->c_str() <<
  2455. " is written by WRITE_FILE (or FILE WRITE) command and should "
  2456. "not be used as input to CMake. Please use CONFIGURE_FILE to "
  2457. "be safe. Refer to the note next to FILE WRITE command.";
  2458. cmSystemTools::Error(str.str().c_str());
  2459. return false;
  2460. }
  2461. }
  2462. return true;
  2463. }
  2464. void cmMakefile::SetProperty(const char* prop, const char* value)
  2465. {
  2466. if (!prop)
  2467. {
  2468. return;
  2469. }
  2470. this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
  2471. }
  2472. const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
  2473. {
  2474. const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
  2475. if (!ret)
  2476. {
  2477. ret = this->GetDefinition(prop);
  2478. }
  2479. return ret;
  2480. }
  2481. const char *cmMakefile::GetProperty(const char* prop)
  2482. {
  2483. return this->GetProperty(prop, cmProperty::DIRECTORY);
  2484. }
  2485. const char *cmMakefile::GetProperty(const char* prop,
  2486. cmProperty::ScopeType scope)
  2487. {
  2488. // watch for specific properties
  2489. if (!strcmp("PARENT_DIRECTORY",prop))
  2490. {
  2491. return this->LocalGenerator->GetParent()
  2492. ->GetMakefile()->GetStartDirectory();
  2493. }
  2494. // watch for specific properties
  2495. if (!strcmp("LISTFILE_STACK",prop))
  2496. {
  2497. std::string tmp;
  2498. for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
  2499. i != this->ListFileStack.end(); ++i)
  2500. {
  2501. if (i != this->ListFileStack.begin())
  2502. {
  2503. tmp += ";";
  2504. }
  2505. tmp += *i;
  2506. }
  2507. this->SetProperty("LISTFILE_STACK",tmp.c_str());
  2508. }
  2509. bool chain = false;
  2510. const char *retVal =
  2511. this->Properties.GetPropertyValue(prop, scope, chain);
  2512. if (chain)
  2513. {
  2514. if(this->LocalGenerator->GetParent())
  2515. {
  2516. return this->LocalGenerator->GetParent()->GetMakefile()->
  2517. GetProperty(prop, scope);
  2518. }
  2519. return this->GetCMakeInstance()->GetProperty(prop,scope);
  2520. }
  2521. return retVal;
  2522. }
  2523. bool cmMakefile::GetPropertyAsBool(const char* prop)
  2524. {
  2525. return cmSystemTools::IsOn(this->GetProperty(prop));
  2526. }
  2527. cmTarget* cmMakefile::FindTarget(const char* name, bool useImportedTargets)
  2528. {
  2529. cmTargets& tgts = this->GetTargets();
  2530. cmTargets::iterator i = tgts.find ( name );
  2531. if ( i != tgts.end() )
  2532. {
  2533. return &i->second;
  2534. }
  2535. if (useImportedTargets)
  2536. {
  2537. cmTargets::iterator impTarget = this->ImportedTargets.find(name);
  2538. if (impTarget != this->ImportedTargets.end())
  2539. {
  2540. return &impTarget->second;
  2541. }
  2542. }
  2543. return 0;
  2544. }
  2545. cmTest* cmMakefile::CreateTest(const char* testName)
  2546. {
  2547. if ( !testName )
  2548. {
  2549. return 0;
  2550. }
  2551. cmTest* test = this->GetTest(testName);
  2552. if ( test )
  2553. {
  2554. return test;
  2555. }
  2556. test = new cmTest;
  2557. test->SetName(testName);
  2558. test->SetMakefile(this);
  2559. this->Tests.push_back(test);
  2560. return test;
  2561. }
  2562. cmTest* cmMakefile::GetTest(const char* testName) const
  2563. {
  2564. if ( !testName )
  2565. {
  2566. return 0;
  2567. }
  2568. std::vector<cmTest*>::const_iterator it;
  2569. for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it )
  2570. {
  2571. if ( strcmp((*it)->GetName(), testName) == 0 )
  2572. {
  2573. return *it;
  2574. }
  2575. }
  2576. return 0;
  2577. }
  2578. const std::vector<cmTest*> *cmMakefile::GetTests() const
  2579. {
  2580. return &this->Tests;
  2581. }
  2582. std::vector<cmTest*> *cmMakefile::GetTests()
  2583. {
  2584. return &this->Tests;
  2585. }
  2586. std::string cmMakefile::GetListFileStack()
  2587. {
  2588. cmOStringStream tmp;
  2589. size_t depth = this->ListFileStack.size();
  2590. std::deque<cmStdString>::iterator it = this->ListFileStack.end();
  2591. do
  2592. {
  2593. --it;
  2594. tmp << "\n[";
  2595. tmp << depth;
  2596. tmp << "]\t";
  2597. tmp << *it;
  2598. depth--;
  2599. }
  2600. while (it != this->ListFileStack.begin());
  2601. return tmp.str();
  2602. }
  2603. // define properties
  2604. void cmMakefile::DefineProperties(cmake *cm)
  2605. {
  2606. cm->DefineProperty
  2607. ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
  2608. "Addditional files to clean during the make clean stage.",
  2609. "A list of files that will be cleaned as a part of the "
  2610. "\"make clean\" stage. ");
  2611. cm->DefineProperty
  2612. ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
  2613. "Should the output of custom commands be left.",
  2614. "If this is true then the outputs of custom commands for this "
  2615. "directory will not be removed during the \"make clean\" stage. ");
  2616. cm->DefineProperty
  2617. ("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS", cmProperty::DIRECTORY,
  2618. "Allow loops to have non-matching closing statements.",
  2619. "If this is set then the closing statement of control "
  2620. "structures in CMake will not require an exact match to the "
  2621. "opening statement. For example IF(foo) will not require "
  2622. "ENDIF(foo) but simple ENDIF() will work.",
  2623. true);
  2624. cm->DefineProperty
  2625. ("LISTFILE_STACK", cmProperty::DIRECTORY,
  2626. "The current stack of listfiles being processed.",
  2627. "This property is mainly useful when trying to debug errors "
  2628. "in your CMake scripts. It returns a list of what list files "
  2629. "are currently being processed, in order. So if one listfile "
  2630. "does an INCLUDE command then that is effectively pushing "
  2631. "the included listfile onto the stack.");
  2632. cm->DefineProperty
  2633. ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
  2634. "A cmake file that will be included when ctest is run.",
  2635. "If you specify TEST_INCLUDE_FILE, that file will be "
  2636. "included and processed when ctest is run on the directory.");
  2637. cm->DefineProperty
  2638. ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
  2639. "Exclude the target from the all target.",
  2640. "A property on a target that indicates if the target is excluded "
  2641. "from the default build target. If it is not, then with a Makefile "
  2642. "for example typing make will couse this target to be built as well. "
  2643. "The same concept applies to the default build of other generators.",
  2644. true);
  2645. }