cmMakefile.cxx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #ifdef _MSC_VER
  2. #pragma warning ( disable : 4786 )
  3. #endif
  4. #include "cmMakefile.h"
  5. #include "cmClassFile.h"
  6. #include "cmDirectory.h"
  7. #include "cmSystemTools.h"
  8. #include <fstream>
  9. #include <iostream>
  10. // default is not to be building executables
  11. cmMakefile::cmMakefile()
  12. {
  13. m_Executables = false;
  14. }
  15. // call print on all the classes in the makefile
  16. void cmMakefile::Print()
  17. {
  18. for(int i = 0; i < m_Classes.size(); i++)
  19. m_Classes[i].Print();
  20. }
  21. // Parse the given CMakeLists.txt file into a list of classes.
  22. bool cmMakefile::ReadMakefile(const char* filename)
  23. {
  24. m_BuildFlags.SetSourceHomeDirectory(this->GetHomeDirectory());
  25. m_BuildFlags.SetStartDirectory(this->GetCurrentDirectory());
  26. m_BuildFlags.ParseDirectories();
  27. std::ifstream fin(filename);
  28. if(!fin)
  29. {
  30. std::cerr << "error can not open file " << filename << std::endl;
  31. return false;
  32. }
  33. char inbuffer[2048];
  34. while ( fin.getline(inbuffer, 2047 ) )
  35. {
  36. std::string line = inbuffer;
  37. cmClassFile file;
  38. if(line.find("COMPILE_CLASSES") != std::string::npos)
  39. {
  40. if(line.find("\\") != std::string::npos)
  41. {
  42. this->ReadClasses(fin, false);
  43. }
  44. }
  45. #ifdef _WIN32
  46. else if(line.find("WIN32_CLASSES") != std::string::npos)
  47. {
  48. if(line.find("\\") != std::string::npos)
  49. {
  50. this->ReadClasses(fin, false);
  51. }
  52. }
  53. #else
  54. else if(line.find("UNIX_CLASSES") != std::string::npos)
  55. {
  56. if(line.find("\\") != std::string::npos)
  57. {
  58. this->ReadClasses(fin, false);
  59. }
  60. }
  61. #endif
  62. else if(line.find("ABSTRACT_CLASSES") != std::string::npos)
  63. {
  64. if(line.find("\\") != std::string::npos)
  65. {
  66. this->ReadClasses(fin, true);
  67. }
  68. }
  69. else if(line.find("TEMPLATE_INSTANCE_DIRECTORY") != std::string::npos)
  70. {
  71. this->ReadTemplateInstanceDirectory(line);
  72. }
  73. else if(line.find("SUBDIRS") != std::string::npos)
  74. {
  75. if(line.find("\\") != std::string::npos)
  76. {
  77. cmSystemTools::ReadList(m_SubDirectories, fin);
  78. }
  79. }
  80. else if(line.find("EXECUTABLES") != std::string::npos)
  81. {
  82. if(line.find("\\") != std::string::npos)
  83. {
  84. this->ReadClasses(fin, false);
  85. m_Executables = true;
  86. }
  87. }
  88. else if(line.find("BEGIN MAKE VERBATIM") != std::string::npos)
  89. {
  90. char inbuffer[2048];
  91. bool done = false;
  92. m_MakeVerbatim.push_back("# Begin CMakeLists Verbatim\n");
  93. while(!done)
  94. {
  95. fin.getline(inbuffer, 2047);
  96. m_MakeVerbatim.push_back(inbuffer);
  97. if((m_MakeVerbatim.end()-1)->find("END MAKE VERBATIM")
  98. != std::string::npos )
  99. {
  100. done = true;
  101. *(m_MakeVerbatim.end()-1) = "# End CMakeLists VERBATIM\n\n";
  102. }
  103. }
  104. }
  105. else if(line.find("ME") != std::string::npos)
  106. {
  107. size_t mestart = line.find("ME");
  108. size_t start = line.find("=");
  109. if(start != std::string::npos && start > mestart )
  110. {
  111. start++;
  112. while(line[start] == ' ' && start < line.size())
  113. {
  114. start++;
  115. }
  116. size_t end = line.size()-1;
  117. while(line[end] == ' ' && end > start)
  118. {
  119. end--;
  120. }
  121. this->SetLibraryName(line.substr(start, end).c_str());
  122. }
  123. }
  124. }
  125. return true;
  126. }
  127. // Read a list from the Makefile stream
  128. void cmMakefile::ReadClasses(std::ifstream& fin,
  129. bool abstract)
  130. {
  131. char inbuffer[2048];
  132. bool done = false;
  133. while (!done)
  134. {
  135. // read a line from the makefile
  136. fin.getline(inbuffer, 2047);
  137. // convert to a string class
  138. std::string classname = inbuffer;
  139. // if the line does not end in \ then we are at the
  140. // end of the list
  141. if(classname.find('\\') == std::string::npos)
  142. {
  143. done = true;
  144. }
  145. // remove extra spaces and \ from the class name
  146. classname = cmSystemTools::CleanUpName(classname.c_str());
  147. // if this is not an abstract list then add new class
  148. // to the list of classes in this makefile
  149. if(!abstract)
  150. {
  151. cmClassFile file;
  152. file.SetName(classname.c_str(), this->GetCurrentDirectory());
  153. file.m_AbstractClass = false;
  154. m_Classes.push_back(file);
  155. }
  156. else
  157. {
  158. // if this is an abstract list, then look
  159. // for an existing class and set it to abstract
  160. for(int i = 0; i < m_Classes.size(); i++)
  161. {
  162. if(m_Classes[i].m_ClassName == classname)
  163. {
  164. m_Classes[i].m_AbstractClass = true;
  165. break;
  166. }
  167. }
  168. }
  169. }
  170. }
  171. // Find all of the files in dir as specified from this line:
  172. // TEMPLATE_INSTANCE_DIRECTORY = dir
  173. // Add all the files to the m_Classes array.
  174. void cmMakefile::ReadTemplateInstanceDirectory(std::string& line)
  175. {
  176. std::string::size_type start = line.find("=");
  177. if(start != std::string::npos)
  178. {
  179. std::string dirname = line.substr(start+1, line.size());
  180. dirname = cmSystemTools::CleanUpName(dirname.c_str());
  181. std::string tdir = this->GetCurrentDirectory();
  182. tdir += "/";
  183. tdir += dirname;
  184. // Load all the files in the directory
  185. cmDirectory dir;
  186. if(dir.Load(tdir.c_str()))
  187. {
  188. int numfiles = dir.GetNumberOfFiles();
  189. for(int i =0; i < numfiles; ++i)
  190. {
  191. std::string file = dir.GetFile(i);
  192. // ignore files less than f.cxx in length
  193. if(file.size() > 4)
  194. {
  195. // Remove the extension
  196. std::string::size_type dotpos = file.rfind(".");
  197. file = file.substr(0, dotpos);
  198. std::string fullname = dirname;
  199. fullname += "/";
  200. fullname += file;
  201. // add the file as a class file so
  202. // depends can be done
  203. cmClassFile cmfile;
  204. cmfile.SetName(fullname.c_str(), this->GetCurrentDirectory());
  205. cmfile.m_AbstractClass = false;
  206. m_Classes.push_back(cmfile);
  207. }
  208. }
  209. }
  210. else
  211. {
  212. std::cerr << "Error can not open template instance directory "
  213. << dirname.c_str() << std::endl;
  214. }
  215. }
  216. }