cmMakefile.cxx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2000 National Library of Medicine
  8. All rights reserved.
  9. See COPYRIGHT.txt for copyright details.
  10. =========================================================================*/
  11. #include "cmMakefile.h"
  12. #include "cmCommand.h"
  13. #include "cmStandardIncludes.h"
  14. #include "cmSourceFile.h"
  15. #include "cmDirectory.h"
  16. #include "cmSystemTools.h"
  17. #include "cmMakefileGenerator.h"
  18. #include "cmCommands.h"
  19. #include "cmCacheManager.h"
  20. #include "cmFunctionBlocker.h"
  21. // default is not to be building executables
  22. cmMakefile::cmMakefile()
  23. {
  24. // Setup the default include file regular expression.
  25. // Should be changed to something like "\\.(h|hh|hpp|hxx)$" or "^.*$"
  26. m_IncludeFileRegularExpression = "^itk|^vtk|^vnl|^vcl|^f2c";
  27. m_DefineFlags = " ";
  28. m_MakefileGenerator = 0;
  29. this->AddSourceGroup("", "^.*$");
  30. this->AddSourceGroup("Source Files", "\\.(cpp|C|c|cxx|rc|def|r|odl|idl|hpj|bat)$");
  31. this->AddSourceGroup("Header Files", "\\.(h|hh|hpp|hxx|hm|inl)$");
  32. this->AddDefaultCommands();
  33. this->AddDefaultDefinitions();
  34. }
  35. void cmMakefile::AddDefaultCommands()
  36. {
  37. std::list<cmCommand*> commands;
  38. GetPredefinedCommands(commands);
  39. for(std::list<cmCommand*>::iterator i = commands.begin();
  40. i != commands.end(); ++i)
  41. {
  42. this->AddCommand(*i);
  43. }
  44. #ifdef _WIN32
  45. this->AddDefinition("WIN32", "1");
  46. #else
  47. this->AddDefinition("UNIX", "1");
  48. #endif
  49. // Cygwin is more like unix so enable the unix commands
  50. #if defined(__CYGWIN__)
  51. this->AddDefinition("UNIX", "1");
  52. #endif
  53. }
  54. cmMakefile::~cmMakefile()
  55. {
  56. for(unsigned int i=0; i < m_UsedCommands.size(); i++)
  57. {
  58. delete m_UsedCommands[i];
  59. }
  60. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  61. j != m_Commands.end(); ++j)
  62. {
  63. delete (*j).second;
  64. }
  65. delete m_MakefileGenerator;
  66. }
  67. void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>& v) const
  68. {
  69. std::cout << s << ": ( \n";
  70. for(std::vector<std::string>::const_iterator i = v.begin();
  71. i != v.end(); ++i)
  72. {
  73. std::cout << (*i).c_str() << " ";
  74. }
  75. std::cout << " )\n";
  76. }
  77. // call print on all the classes in the makefile
  78. void cmMakefile::Print() const
  79. {
  80. // print the class lists
  81. std::cout << "classes:\n";
  82. for(SourceMap::const_iterator l = m_Sources.begin();
  83. l != m_Sources.end(); l++)
  84. {
  85. std::cout << " Class list named: " << l->first << std::endl;
  86. for(std::vector<cmSourceFile>::const_iterator i = l->second.begin();
  87. i != l->second.end(); i++)
  88. {
  89. i->Print();
  90. }
  91. }
  92. std::cout << " m_Targets: ";
  93. for (cmTargets::const_iterator l = m_Targets.begin();
  94. l != m_Targets.end(); l++)
  95. {
  96. std::cout << l->first << std::endl;
  97. }
  98. std::cout << " m_CurrentOutputDirectory; " <<
  99. m_CurrentOutputDirectory.c_str() << std::endl;
  100. std::cout << " m_StartOutputDirectory; " <<
  101. m_StartOutputDirectory.c_str() << std::endl;
  102. std::cout << " m_HomeOutputDirectory; " <<
  103. m_HomeOutputDirectory.c_str() << std::endl;
  104. std::cout << " m_cmCurrentDirectory; " <<
  105. m_cmCurrentDirectory.c_str() << std::endl;
  106. std::cout << " m_cmStartDirectory; " <<
  107. m_cmStartDirectory.c_str() << std::endl;
  108. std::cout << " m_cmHomeDirectory; " <<
  109. m_cmHomeDirectory.c_str() << std::endl;
  110. std::cout << " m_ProjectName; " << m_ProjectName.c_str() << std::endl;
  111. this->PrintStringVector("m_SubDirectories ", m_SubDirectories);
  112. this->PrintStringVector("m_MakeVerbatim ", m_MakeVerbatim);
  113. this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories);
  114. this->PrintStringVector("m_LinkDirectories", m_LinkDirectories);
  115. this->PrintStringVector("m_Utilities", m_Utilities);
  116. this->PrintStringVector("m_UtilityDirectories", m_UtilityDirectories);
  117. }
  118. // Parse the given CMakeLists.txt file into a list of classes.
  119. // Reads in current CMakeLists file and all parent CMakeLists files
  120. // executing all inherited commands in the parents
  121. bool cmMakefile::ReadListFile(const char* filename)
  122. {
  123. // is there a parent CMakeLists file that does not go beyond the
  124. // Home directory? if so recurse and read in that List file
  125. std::string parentList = this->GetParentListFileName(filename);
  126. if (parentList != "")
  127. {
  128. // save the current directory
  129. std::string srcdir = m_cmCurrentDirectory;
  130. std::string bindir = m_CurrentOutputDirectory;
  131. // compute the new current directories
  132. std::string::size_type pos = m_cmCurrentDirectory.rfind('/');
  133. if(pos != std::string::npos)
  134. {
  135. m_cmCurrentDirectory = m_cmCurrentDirectory.substr(0, pos);
  136. }
  137. pos = m_CurrentOutputDirectory.rfind('/');
  138. if(pos != std::string::npos)
  139. {
  140. m_CurrentOutputDirectory = m_CurrentOutputDirectory.substr(0, pos);
  141. }
  142. this->ReadListFile(parentList.c_str());
  143. // restore the current directory
  144. m_cmCurrentDirectory = srcdir;
  145. m_CurrentOutputDirectory = bindir;
  146. }
  147. // are we at the start CMakeLists file or are we processing a parent
  148. // lists file
  149. bool inheriting = (m_cmCurrentDirectory != m_cmStartDirectory);
  150. // Now read the input file
  151. std::ifstream fin(filename);
  152. if(!fin)
  153. {
  154. cmSystemTools::Error("error can not open file ", filename);
  155. return false;
  156. }
  157. std::string name;
  158. std::vector<std::string> arguments;
  159. while ( fin )
  160. {
  161. if(cmSystemTools::ParseFunction(fin, name, arguments) &&
  162. !this->IsFunctionBlocked(name.c_str(),arguments))
  163. {
  164. // Special command that needs to be removed when
  165. // ADD_COMMAND is implemented
  166. if(name == "VERBATIM")
  167. {
  168. if (!inheriting)
  169. {
  170. m_MakeVerbatim = arguments;
  171. }
  172. }
  173. else
  174. {
  175. RegisteredCommandsMap::iterator pos = m_Commands.find(name);
  176. if(pos != m_Commands.end())
  177. {
  178. cmCommand* rm = (*pos).second;
  179. cmCommand* usedCommand = rm->Clone();
  180. usedCommand->SetMakefile(this);
  181. bool keepCommand = false;
  182. if(usedCommand->GetEnabled())
  183. {
  184. // if not running in inherit mode or
  185. // if the command is inherited then Invoke it.
  186. if(!inheriting || usedCommand->IsInherited())
  187. {
  188. if(!usedCommand->Invoke(arguments))
  189. {
  190. cmSystemTools::Error(usedCommand->GetName(),
  191. ": Error : \n",
  192. usedCommand->GetError(),
  193. m_cmCurrentDirectory.c_str());
  194. }
  195. else
  196. {
  197. // use the command
  198. keepCommand = true;
  199. m_UsedCommands.push_back(usedCommand);
  200. }
  201. }
  202. }
  203. // if the Cloned command was not used
  204. // then delete it
  205. if(!keepCommand)
  206. {
  207. delete usedCommand;
  208. }
  209. }
  210. else
  211. {
  212. cmSystemTools::Error("unknown CMake command ", name.c_str());
  213. }
  214. }
  215. }
  216. }
  217. return true;
  218. }
  219. cmSourceFile *cmMakefile::GetSource(const char *srclist, const char *cname)
  220. {
  221. SourceMap::iterator sl = m_Sources.find(srclist);
  222. // find the src list
  223. if (sl == m_Sources.end())
  224. {
  225. return 0;
  226. }
  227. // find the class
  228. for (std::vector<cmSourceFile>::iterator i = sl->second.begin();
  229. i != sl->second.end(); ++i)
  230. {
  231. if (i->GetSourceName() == cname)
  232. {
  233. return &(*i);
  234. }
  235. }
  236. return 0;
  237. }
  238. void cmMakefile::AddCommand(cmCommand* wg)
  239. {
  240. std::string name = wg->GetName();
  241. m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
  242. }
  243. // Set the make file
  244. void cmMakefile::SetMakefileGenerator(cmMakefileGenerator* mf)
  245. {
  246. delete m_MakefileGenerator;
  247. m_MakefileGenerator = mf;
  248. }
  249. // Generate the output file
  250. void cmMakefile::GenerateMakefile()
  251. {
  252. // do all the variable expansions here
  253. this->ExpandVariables();
  254. // set the makefile on the generator
  255. m_MakefileGenerator->SetMakefile(this);
  256. // give all the commands a chance to do something
  257. // after the file has been parsed before generation
  258. for(std::vector<cmCommand*>::iterator i = m_UsedCommands.begin();
  259. i != m_UsedCommands.end(); ++i)
  260. {
  261. (*i)->FinalPass();
  262. }
  263. // now do the generation
  264. m_MakefileGenerator->GenerateMakefile();
  265. }
  266. void cmMakefile::AddSource(cmSourceFile& cmfile, const char *srclist)
  267. {
  268. m_Sources[srclist].push_back(cmfile);
  269. }
  270. void cmMakefile::AddCustomCommand(const char* source,
  271. const char* command,
  272. const std::vector<std::string>& depends,
  273. const std::vector<std::string>& outputs,
  274. const char *target)
  275. {
  276. // find the target,
  277. if (m_Targets.find(target) != m_Targets.end())
  278. {
  279. cmCustomCommand cc(source,command,depends,outputs);
  280. m_Targets[target].GetCustomCommands().push_back(cc);
  281. }
  282. }
  283. void cmMakefile::AddCustomCommand(const char* source,
  284. const char* command,
  285. const std::vector<std::string>& depends,
  286. const char* output,
  287. const char *target)
  288. {
  289. std::vector<std::string> outputs;
  290. outputs.push_back(output);
  291. this->AddCustomCommand(source, command, depends, outputs, target);
  292. }
  293. void cmMakefile::AddDefineFlag(const char* flag)
  294. {
  295. m_DefineFlags += " ";
  296. m_DefineFlags += flag;
  297. }
  298. void cmMakefile::AddUtility(const char* util)
  299. {
  300. m_Utilities.push_back(util);
  301. }
  302. void cmMakefile::AddUtilityDirectory(const char* dir)
  303. {
  304. m_UtilityDirectories.push_back(dir);
  305. }
  306. void cmMakefile::AddLinkLibrary(const char* lib, LinkLibraryType llt)
  307. {
  308. m_LinkLibraries.push_back(
  309. std::pair<std::string, LinkLibraryType>(lib,llt));
  310. }
  311. void cmMakefile::AddLinkLibrary(const char* lib)
  312. {
  313. this->AddLinkLibrary(lib,GENERAL);
  314. }
  315. void cmMakefile::AddLinkDirectory(const char* dir)
  316. {
  317. m_LinkDirectories.push_back(dir);
  318. }
  319. void cmMakefile::AddSubDirectory(const char* sub)
  320. {
  321. m_SubDirectories.push_back(sub);
  322. }
  323. void cmMakefile::AddIncludeDirectory(const char* inc)
  324. {
  325. m_IncludeDirectories.push_back(inc);
  326. }
  327. void cmMakefile::AddDefinition(const char* name, const char* value)
  328. {
  329. m_Definitions.insert(DefinitionMap::value_type(name, value));
  330. }
  331. void cmMakefile::AddDefinition(const char* name, bool value)
  332. {
  333. if(value)
  334. {
  335. m_Definitions.insert(DefinitionMap::value_type(name, "ON"));
  336. }
  337. else
  338. {
  339. m_Definitions.insert(DefinitionMap::value_type(name, "OFF"));
  340. }
  341. }
  342. void cmMakefile::SetProjectName(const char* p)
  343. {
  344. m_ProjectName = p;
  345. }
  346. void cmMakefile::AddLibrary(const char* lname, const std::vector<std::string> &srcs)
  347. {
  348. cmTarget target;
  349. target.SetIsALibrary(1);
  350. target.GetSourceLists() = srcs;
  351. m_Targets.insert(cmTargets::value_type(lname,target));
  352. }
  353. void cmMakefile::AddExecutable(const char *exeName,
  354. const std::vector<std::string> &srcs)
  355. {
  356. cmTarget target;
  357. target.SetIsALibrary(0);
  358. target.GetSourceLists() = srcs;
  359. m_Targets.insert(cmTargets::value_type(exeName,target));
  360. }
  361. void cmMakefile::AddSourceGroup(const char* name, const char* regex)
  362. {
  363. // First see if the group exists. If so, replace its regular expression.
  364. for(std::vector<cmSourceGroup>::iterator sg = m_SourceGroups.begin();
  365. sg != m_SourceGroups.end(); ++sg)
  366. {
  367. std::string sgName = sg->GetName();
  368. if(sgName == name)
  369. {
  370. // We only want to set the regular expression. If there are already
  371. // source files in the group, we don't want to remove them.
  372. sg->SetGroupRegex(regex);
  373. return;
  374. }
  375. }
  376. // The group doesn't exist. Add it.
  377. m_SourceGroups.push_back(cmSourceGroup(name, regex));
  378. }
  379. void cmMakefile::AddExtraDirectory(const char* dir)
  380. {
  381. m_AuxSourceDirectories.push_back(dir);
  382. }
  383. // return the file name for the parent CMakeLists file to the
  384. // one passed in. Zero is returned if the CMakeLists file is the
  385. // one in the home directory or if for some reason a parent cmake lists
  386. // file cannot be found.
  387. std::string cmMakefile::GetParentListFileName(const char *currentFileName)
  388. {
  389. // extract the directory name
  390. std::string parentFile;
  391. std::string listsDir = currentFileName;
  392. std::string::size_type pos = listsDir.rfind('/');
  393. // if we could not find the directory return 0
  394. if(pos == std::string::npos)
  395. {
  396. return parentFile;
  397. }
  398. listsDir = listsDir.substr(0, pos);
  399. // if we are in the home directory then stop, return 0
  400. if(m_cmHomeDirectory == listsDir)
  401. {
  402. return parentFile;
  403. }
  404. // is there a parent directory we can check
  405. pos = listsDir.rfind('/');
  406. // if we could not find the directory return 0
  407. if(pos == std::string::npos)
  408. {
  409. return parentFile;
  410. }
  411. listsDir = listsDir.substr(0, pos);
  412. // is there a CMakeLists.txt file in the parent directory ?
  413. parentFile = listsDir;
  414. parentFile += "/CMakeLists.txt";
  415. if(!cmSystemTools::FileExists(parentFile.c_str()))
  416. {
  417. parentFile = "";
  418. return parentFile;
  419. }
  420. return parentFile;
  421. }
  422. // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
  423. // include and library directories.
  424. void cmMakefile::ExpandVariables()
  425. {
  426. // Now expand varibles in the include and link strings
  427. std::vector<std::string>::iterator j, begin, end;
  428. begin = m_IncludeDirectories.begin();
  429. end = m_IncludeDirectories.end();
  430. for(j = begin; j != end; ++j)
  431. {
  432. this->ExpandVariablesInString(*j);
  433. }
  434. begin = m_LinkDirectories.begin();
  435. end = m_LinkDirectories.end();
  436. for(j = begin; j != end; ++j)
  437. {
  438. this->ExpandVariablesInString(*j);
  439. }
  440. LinkLibraries::iterator j2, end2;
  441. j2 = m_LinkLibraries.begin();
  442. end2 = m_LinkLibraries.end();
  443. for(; j2 != end2; ++j2)
  444. {
  445. this->ExpandVariablesInString(j2->first);
  446. }
  447. }
  448. const char* cmMakefile::GetDefinition(const char* name)
  449. {
  450. DefinitionMap::iterator pos = m_Definitions.find(name);
  451. if(pos != m_Definitions.end())
  452. {
  453. return (*pos).second.c_str();
  454. }
  455. return 0;
  456. }
  457. int cmMakefile::DumpDocumentationToFile(const char *fileName)
  458. {
  459. // Open the supplied filename
  460. std::ofstream f;
  461. f.open(fileName, std::ios::out);
  462. if ( f.fail() )
  463. {
  464. return 0;
  465. }
  466. // Loop over all registered commands and print out documentation
  467. const char *name;
  468. const char *terse;
  469. const char *full;
  470. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  471. j != m_Commands.end(); ++j)
  472. {
  473. name = (*j).second->GetName();
  474. terse = (*j).second->GetTerseDocumentation();
  475. full = (*j).second->GetFullDocumentation();
  476. f << name << " - " << terse << std::endl
  477. << "Usage: " << full << std::endl << std::endl;
  478. }
  479. return 1;
  480. }
  481. void cmMakefile::ExpandVariablesInString(std::string& source) const
  482. {
  483. for(DefinitionMap::const_iterator i = m_Definitions.begin();
  484. i != m_Definitions.end(); ++i)
  485. {
  486. std::string variable = "${";
  487. variable += (*i).first;
  488. variable += "}";
  489. cmSystemTools::ReplaceString(source, variable.c_str(),
  490. (*i).second.c_str());
  491. variable = "@";
  492. variable += (*i).first;
  493. variable += "@";
  494. cmSystemTools::ReplaceString(source, variable.c_str(),
  495. (*i).second.c_str());
  496. }
  497. }
  498. // recursive function to create a vector of cmMakefile objects
  499. // This is done by reading the sub directory CMakeLists.txt files,
  500. // then calling this function with the new cmMakefile object
  501. void
  502. cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>&
  503. makefiles)
  504. {
  505. // loop over all the sub directories of this makefile
  506. const std::vector<std::string>& subdirs = this->GetSubDirectories();
  507. for(std::vector<std::string>::const_iterator i = subdirs.begin();
  508. i != subdirs.end(); ++i)
  509. {
  510. std::string subdir = *i;
  511. // Create a path to the list file in the sub directory
  512. std::string listFile = this->GetCurrentDirectory();
  513. listFile += "/";
  514. listFile += subdir;
  515. listFile += "/CMakeLists.txt";
  516. // if there is a CMakeLists.txt file read it
  517. if(!cmSystemTools::FileExists(listFile.c_str()))
  518. {
  519. cmSystemTools::Error("CMakeLists.txt file missing from sub directory:",
  520. listFile.c_str());
  521. }
  522. else
  523. {
  524. cmMakefile* mf = new cmMakefile;
  525. makefiles.push_back(mf);
  526. // initialize new makefile
  527. mf->SetHomeOutputDirectory(this->GetHomeOutputDirectory());
  528. mf->SetHomeDirectory(this->GetHomeDirectory());
  529. // add the subdir to the start output directory
  530. std::string outdir = this->GetStartOutputDirectory();
  531. outdir += "/";
  532. outdir += subdir;
  533. mf->SetStartOutputDirectory(outdir.c_str());
  534. // add the subdir to the start source directory
  535. std::string currentDir = this->GetStartDirectory();
  536. currentDir += "/";
  537. currentDir += subdir;
  538. mf->SetStartDirectory(currentDir.c_str());
  539. // Parse the CMakeLists.txt file
  540. currentDir += "/CMakeLists.txt";
  541. mf->MakeStartDirectoriesCurrent();
  542. mf->ReadListFile(currentDir.c_str());
  543. // recurse into nextDir
  544. mf->FindSubDirectoryCMakeListsFiles(makefiles);
  545. }
  546. }
  547. }
  548. void cmMakefile::GenerateCacheOnly()
  549. {
  550. std::vector<cmMakefile*> makefiles;
  551. this->FindSubDirectoryCMakeListsFiles(makefiles);
  552. for(std::vector<cmMakefile*>::iterator i = makefiles.begin();
  553. i != makefiles.end(); ++i)
  554. {
  555. cmMakefile* mf = *i;
  556. std::string source = mf->GetHomeDirectory();
  557. source += "/CMake/CMakeMakefileTemplate.in";
  558. cmSystemTools::MakeDirectory(mf->GetStartOutputDirectory());
  559. std::string dest = mf->GetStartOutputDirectory();
  560. dest += "/Makefile";
  561. std::ofstream fout(dest.c_str());
  562. if(!fout)
  563. {
  564. cmSystemTools::Error("Failed to open file for write " , dest.c_str());
  565. }
  566. else
  567. {
  568. if(strcmp(mf->GetHomeDirectory(),
  569. mf->GetHomeOutputDirectory()) == 0)
  570. {
  571. fout << "srcdir = .\n\n";
  572. }
  573. else
  574. {
  575. fout << "srcdir = " << mf->GetStartDirectory() << "\n";
  576. fout << "VPATH = " << mf->GetStartDirectory() << "\n";
  577. }
  578. }
  579. fout << "include "
  580. << mf->GetHomeOutputDirectory() << "/CMake/CMakeMaster.make\n";
  581. }
  582. for(unsigned int i =0; i < makefiles.size(); ++i)
  583. {
  584. delete makefiles[i];
  585. }
  586. }
  587. /**
  588. * Add the default definitions to the makefile. These values must not
  589. * be dependent on anything that isn't known when this cmMakefile instance
  590. * is constructed.
  591. */
  592. void cmMakefile::AddDefaultDefinitions()
  593. {
  594. #if defined(_WIN32) && !defined(__CYGWIN__)
  595. this->AddDefinition("CMAKE_CFG_OUTDIR","$(OUTDIR)");
  596. #else
  597. this->AddDefinition("CMAKE_CFG_OUTDIR",".");
  598. #endif
  599. }
  600. /**
  601. * Find a source group whose regular expression matches the filename
  602. * part of the given source name. Search backward through the list of
  603. * source groups, and take the first matching group found. This way
  604. * non-inherited SOURCE_GROUP commands will have precedence over
  605. * inherited ones.
  606. */
  607. cmSourceGroup&
  608. cmMakefile::FindSourceGroup(const char* source,
  609. std::vector<cmSourceGroup> &groups)
  610. {
  611. std::string file = source;
  612. std::string::size_type pos = file.rfind('/');
  613. if(pos != std::string::npos)
  614. {
  615. file = file.substr(pos, file.length()-pos);
  616. }
  617. for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
  618. sg != groups.rend(); ++sg)
  619. {
  620. if(sg->Matches(file.c_str()))
  621. {
  622. return *sg;
  623. }
  624. }
  625. // Shouldn't get here, but just in case, return the default group.
  626. return groups.front();
  627. }
  628. bool cmMakefile::IsFunctionBlocked(const char *name,
  629. std::vector<std::string> &args) const
  630. {
  631. // loop over all function blockers to see if any block this command
  632. std::set<cmFunctionBlocker *>::const_iterator pos;
  633. for (pos = m_FunctionBlockers.begin();
  634. pos != m_FunctionBlockers.end(); ++pos)
  635. {
  636. if ((*pos)->IsFunctionBlocked(name, args, *this))
  637. {
  638. return true;
  639. }
  640. }
  641. return false;
  642. }
  643. void cmMakefile::RemoveFunctionBlocker(const char *name,
  644. const std::vector<std::string> &args)
  645. {
  646. // loop over all function blockers to see if any block this command
  647. std::set<cmFunctionBlocker *>::const_iterator pos;
  648. for (pos = m_FunctionBlockers.begin();
  649. pos != m_FunctionBlockers.end(); ++pos)
  650. {
  651. if ((*pos)->ShouldRemove(name, args, *this))
  652. {
  653. m_FunctionBlockers.erase(*pos);
  654. return;
  655. }
  656. }
  657. return;
  658. }