cmMakefile.cxx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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 "cmClassFile.h"
  15. #include "cmDirectory.h"
  16. #include "cmSystemTools.h"
  17. #include "cmMakefileGenerator.h"
  18. #include "cmCommands.h"
  19. // default is not to be building executables
  20. cmMakefile::cmMakefile()
  21. {
  22. m_DefineFlags = " ";
  23. m_Executables = false;
  24. m_MakefileGenerator = 0;
  25. this->AddDefaultCommands();
  26. }
  27. void cmMakefile::AddDefaultCommands()
  28. {
  29. std::list<cmCommand*> commands;
  30. GetPredefinedCommands(commands);
  31. for(std::list<cmCommand*>::iterator i = commands.begin();
  32. i != commands.end(); ++i)
  33. {
  34. this->AddCommand(*i);
  35. }
  36. #ifdef _WIN32
  37. this->AddDefinition("WIN32", "1");
  38. #else
  39. this->AddDefinition("UNIX", "1");
  40. #endif
  41. // Cygwin is more like unix so enable the unix commands
  42. #if defined(__CYGWIN__)
  43. this->AddDefinition("UNIX", "1");
  44. #endif
  45. }
  46. cmMakefile::~cmMakefile()
  47. {
  48. for(int i=0; i < m_UsedCommands.size(); i++)
  49. {
  50. delete m_UsedCommands[i];
  51. }
  52. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  53. j != m_Commands.end(); ++j)
  54. {
  55. delete (*j).second;
  56. }
  57. delete m_MakefileGenerator;
  58. }
  59. void cmMakefile::PrintStringVector(const char* s, std::vector<std::string>& v)
  60. {
  61. std::cout << s << ": ( \n";
  62. for(std::vector<std::string>::iterator i = v.begin();
  63. i != v.end(); ++i)
  64. {
  65. std::cout << (*i).c_str() << " ";
  66. }
  67. std::cout << " )\n";
  68. }
  69. // call print on all the classes in the makefile
  70. void cmMakefile::Print()
  71. {
  72. std::cout << "classes:\n";
  73. for(unsigned int i = 0; i < m_Classes.size(); i++)
  74. m_Classes[i].Print();
  75. std::cout << " m_OutputDirectory; " <<
  76. m_OutputDirectory.c_str() << std::endl;
  77. std::cout << " m_OutputHomeDirectory; " <<
  78. m_OutputHomeDirectory.c_str() << std::endl;
  79. std::cout << " m_cmHomeDirectory; " <<
  80. m_cmHomeDirectory.c_str() << std::endl;
  81. std::cout << " m_cmCurrentDirectory; " <<
  82. m_cmCurrentDirectory.c_str() << std::endl;
  83. std::cout << " m_LibraryName; " << m_LibraryName.c_str() << std::endl;
  84. std::cout << " m_ProjectName; " << m_ProjectName.c_str() << std::endl;
  85. this->PrintStringVector("m_SubDirectories ", m_SubDirectories);
  86. this->PrintStringVector("m_MakeVerbatim ", m_MakeVerbatim);
  87. this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories);
  88. this->PrintStringVector("m_LinkDirectories", m_LinkDirectories);
  89. this->PrintStringVector("m_LinkLibraries", m_LinkLibraries);
  90. this->PrintStringVector("m_LinkLibrariesWin32", m_LinkLibrariesWin32);
  91. this->PrintStringVector("m_LinkLibrariesUnix", m_LinkLibrariesUnix);
  92. }
  93. // Parse the given CMakeLists.txt file into a list of classes.
  94. bool cmMakefile::ReadMakefile(const char* filename, bool inheriting)
  95. {
  96. // If not being called from ParseDirectory which
  97. // sets the inheriting flag, then parse up the
  98. // tree and collect inherited parameters
  99. if(!inheriting)
  100. {
  101. cmSystemTools::ConvertToUnixSlashes(m_cmCurrentDirectory);
  102. m_SourceHomeDirectory = m_cmHomeDirectory;
  103. cmSystemTools::ConvertToUnixSlashes(m_SourceHomeDirectory);
  104. // if this is already the top level directory then
  105. if(m_SourceHomeDirectory != m_cmCurrentDirectory)
  106. {
  107. this->ParseDirectory(m_cmCurrentDirectory.c_str());
  108. }
  109. }
  110. // Now read the input file
  111. std::ifstream fin(filename);
  112. if(!fin)
  113. {
  114. cmSystemTools::Error("error can not open file ", filename);
  115. return false;
  116. }
  117. std::string name;
  118. std::vector<std::string> arguments;
  119. while ( fin )
  120. {
  121. if(cmSystemTools::ParseFunction(fin, name, arguments) )
  122. {
  123. // Special command that needs to be removed when
  124. // ADD_COMMAND is implemented
  125. if(name == "VERBATIM")
  126. {
  127. if(!inheriting)
  128. {
  129. m_MakeVerbatim = arguments;
  130. }
  131. }
  132. else
  133. {
  134. RegisteredCommandsMap::iterator pos = m_Commands.find(name);
  135. if(pos != m_Commands.end())
  136. {
  137. cmCommand* rm = (*pos).second;
  138. cmCommand* usedCommand = rm->Clone();
  139. usedCommand->SetMakefile(this);
  140. usedCommand->LoadCache();
  141. bool keepCommand = false;
  142. if(usedCommand->GetEnabled())
  143. {
  144. // if not running in inherit mode or
  145. // if the command is inherited then Invoke it.
  146. if(!inheriting || usedCommand->IsInherited())
  147. {
  148. if(!usedCommand->Invoke(arguments))
  149. {
  150. cmSystemTools::Error(usedCommand->GetError());
  151. }
  152. else
  153. {
  154. // use the command
  155. keepCommand = true;
  156. m_UsedCommands.push_back(usedCommand);
  157. }
  158. }
  159. }
  160. // if the Cloned command was not used
  161. // then delete it
  162. if(!keepCommand)
  163. {
  164. delete usedCommand;
  165. }
  166. }
  167. else
  168. {
  169. cmSystemTools::Error("unknown CMake function", name.c_str());
  170. }
  171. }
  172. }
  173. }
  174. return true;
  175. }
  176. void cmMakefile::AddCommand(cmCommand* wg)
  177. {
  178. std::string name = wg->GetName();
  179. m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
  180. }
  181. // Set the make file
  182. void cmMakefile::SetMakefileGenerator(cmMakefileGenerator* mf)
  183. {
  184. delete m_MakefileGenerator;
  185. m_MakefileGenerator = mf;
  186. }
  187. // Generate the output file
  188. void cmMakefile::GenerateMakefile()
  189. {
  190. // do all the variable expansions here
  191. this->ExpandVaribles();
  192. // set the makefile on the generator
  193. m_MakefileGenerator->SetMakefile(this);
  194. // give all the commands a chance to do something
  195. // after the file has been parsed before generation
  196. for(std::vector<cmCommand*>::iterator i = m_UsedCommands.begin();
  197. i != m_UsedCommands.end(); ++i)
  198. {
  199. (*i)->FinalPass();
  200. }
  201. // now do the generation
  202. m_MakefileGenerator->GenerateMakefile();
  203. }
  204. void cmMakefile::AddClass(cmClassFile& cmfile)
  205. {
  206. m_Classes.push_back(cmfile);
  207. }
  208. void cmMakefile::AddCustomCommand(const char* source,
  209. const char* result,
  210. const char* command,
  211. std::vector<std::string>& depends)
  212. {
  213. cmMakefile::customCommand customCommand;
  214. customCommand.m_Source = source;
  215. customCommand.m_Result = result;
  216. customCommand.m_Command = command;
  217. customCommand.m_Depends = depends;
  218. m_CustomCommands.push_back(customCommand);
  219. }
  220. void cmMakefile::AddDefineFlag(const char* flag)
  221. {
  222. m_DefineFlags += " ";
  223. m_DefineFlags += flag;
  224. }
  225. void cmMakefile::AddExecutable(cmClassFile& cf)
  226. {
  227. m_Classes.push_back(cf);
  228. m_Executables = true;
  229. }
  230. void cmMakefile::AddLinkLibrary(const char* lib)
  231. {
  232. m_LinkLibraries.push_back(lib);
  233. }
  234. void cmMakefile::AddLinkDirectory(const char* dir)
  235. {
  236. m_LinkDirectories.push_back(dir);
  237. }
  238. void cmMakefile::AddSubDirectory(const char* sub)
  239. {
  240. m_SubDirectories.push_back(sub);
  241. }
  242. void cmMakefile::AddIncludeDirectory(const char* inc)
  243. {
  244. m_IncludeDirectories.push_back(inc);
  245. }
  246. void cmMakefile::AddDefinition(const char* name, const char* value)
  247. {
  248. m_Definitions.insert(DefinitionMap::value_type(name, value));
  249. }
  250. void cmMakefile::SetProjectName(const char* p)
  251. {
  252. m_ProjectName = p;
  253. }
  254. void cmMakefile::SetLibraryName(const char* l)
  255. {
  256. m_LibraryName = l;
  257. }
  258. void cmMakefile::AddExtraDirectory(const char* dir)
  259. {
  260. m_AuxSourceDirectories.push_back(dir);
  261. }
  262. // Go until directory == m_cmHomeDirectory
  263. // 1. fix slashes
  264. // 2. peal off /dir until home found, go no higher
  265. void cmMakefile::ParseDirectory(const char* dir)
  266. {
  267. std::string listsFile = dir;
  268. listsFile += "/CMakeLists.txt";
  269. if(cmSystemTools::FileExists(listsFile.c_str()))
  270. {
  271. this->ReadMakefile(listsFile.c_str(), true);
  272. }
  273. if(m_SourceHomeDirectory == dir)
  274. {
  275. return;
  276. }
  277. std::string dotdotDir = dir;
  278. std::string::size_type pos = dotdotDir.rfind('/');
  279. if(pos != std::string::npos)
  280. {
  281. dotdotDir = dotdotDir.substr(0, pos);
  282. this->ParseDirectory(dotdotDir.c_str());
  283. }
  284. }
  285. // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
  286. // include and library directories.
  287. void cmMakefile::ExpandVaribles()
  288. {
  289. // make sure binary and source dir are defined
  290. this->AddDefinition("CMAKE_BINARY_DIR", this->GetOutputDirectory());
  291. this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
  292. // Now expand varibles in the include and link strings
  293. std::vector<std::string>::iterator j, begin, end;
  294. begin = m_IncludeDirectories.begin();
  295. end = m_IncludeDirectories.end();
  296. for(j = begin; j != end; ++j)
  297. {
  298. this->ExpandVariblesInString(*j);
  299. }
  300. begin = m_LinkDirectories.begin();
  301. end = m_LinkDirectories.end();
  302. for(j = begin; j != end; ++j)
  303. {
  304. this->ExpandVariblesInString(*j);
  305. }
  306. }
  307. const char* cmMakefile::GetDefinition(const char* name)
  308. {
  309. DefinitionMap::iterator pos = m_Definitions.find(name);
  310. if(pos != m_Definitions.end())
  311. {
  312. return (*pos).second.c_str();
  313. }
  314. return 0;
  315. }
  316. int cmMakefile::DumpDocumentationToFile(const char *fileName)
  317. {
  318. // Open the supplied filename
  319. std::ofstream f;
  320. f.open(fileName, std::ios::out);
  321. if ( f.fail() )
  322. {
  323. return 0;
  324. }
  325. // Loop over all registered commands and print out documentation
  326. const char *name;
  327. const char *terse;
  328. const char *full;
  329. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  330. j != m_Commands.end(); ++j)
  331. {
  332. name = (*j).second->GetName();
  333. terse = (*j).second->GetTerseDocumentation();
  334. full = (*j).second->GetFullDocumentation();
  335. f << name << " - " << terse << std::endl
  336. << "Usage: " << full << std::endl << std::endl;
  337. }
  338. return 1;
  339. }
  340. void cmMakefile::ExpandVariblesInString(std::string& source)
  341. {
  342. for(DefinitionMap::iterator i = m_Definitions.begin();
  343. i != m_Definitions.end(); ++i)
  344. {
  345. std::string variable = "${";
  346. variable += (*i).first;
  347. variable += "}";
  348. cmSystemTools::ReplaceString(source, variable.c_str(),
  349. (*i).second.c_str());
  350. variable = "@";
  351. variable += (*i).first;
  352. variable += "@";
  353. cmSystemTools::ReplaceString(source, variable.c_str(),
  354. (*i).second.c_str());
  355. }
  356. }