cmOutputRequiredFilesCommand.cxx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Insight Consortium. All rights reserved.
  8. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 "cmOutputRequiredFilesCommand.h"
  14. #include "cmMakeDepend.h"
  15. class cmLBDepend : public cmMakeDepend
  16. {
  17. /**
  18. * Compute the depend information for this class.
  19. */
  20. virtual void DependWalk(cmDependInformation* info);
  21. };
  22. void cmLBDepend::DependWalk(cmDependInformation* info)
  23. {
  24. std::ifstream fin(info->m_FullPath.c_str());
  25. if(!fin)
  26. {
  27. cmSystemTools::Error("error can not open ", info->m_FullPath.c_str());
  28. return;
  29. }
  30. char line[255];
  31. while(!fin.eof() && !fin.fail())
  32. {
  33. fin.getline(line, 255);
  34. if(!strncmp(line, "#include", 8))
  35. {
  36. // if it is an include line then create a string class
  37. std::string currentline = line;
  38. size_t qstart = currentline.find('\"', 8);
  39. size_t qend;
  40. // if a quote is not found look for a <
  41. if(qstart == std::string::npos)
  42. {
  43. qstart = currentline.find('<', 8);
  44. // if a < is not found then move on
  45. if(qstart == std::string::npos)
  46. {
  47. cmSystemTools::Error("unknown include directive ",
  48. currentline.c_str() );
  49. continue;
  50. }
  51. else
  52. {
  53. qend = currentline.find('>', qstart+1);
  54. }
  55. }
  56. else
  57. {
  58. qend = currentline.find('\"', qstart+1);
  59. }
  60. // extract the file being included
  61. std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
  62. // see if the include matches the regular expression
  63. if(!m_IncludeFileRegularExpression.find(includeFile))
  64. {
  65. if(m_Verbose)
  66. {
  67. std::string message = "Skipping ";
  68. message += includeFile;
  69. message += " for file ";
  70. message += info->m_FullPath.c_str();
  71. cmSystemTools::Error(message.c_str(), 0);
  72. }
  73. continue;
  74. }
  75. // Add this file and all its dependencies.
  76. this->AddDependency(info, includeFile.c_str());
  77. /// add the cxx file if it exists
  78. std::string cxxFile = includeFile;
  79. std::string::size_type pos = cxxFile.rfind('.');
  80. if(pos != std::string::npos)
  81. {
  82. std::string root = cxxFile.substr(0, pos);
  83. cxxFile = root + ".cxx";
  84. bool found = false;
  85. // try jumping to .cxx .cpp and .c in order
  86. if(cmSystemTools::FileExists(cxxFile.c_str()))
  87. {
  88. found = true;
  89. }
  90. for(std::vector<std::string>::iterator i =
  91. m_IncludeDirectories.begin();
  92. i != m_IncludeDirectories.end(); ++i)
  93. {
  94. std::string path = *i;
  95. path = path + "/";
  96. path = path + cxxFile;
  97. if(cmSystemTools::FileExists(path.c_str()))
  98. {
  99. found = true;
  100. }
  101. }
  102. if (!found)
  103. {
  104. cxxFile = root + ".cpp";
  105. if(cmSystemTools::FileExists(cxxFile.c_str()))
  106. {
  107. found = true;
  108. }
  109. for(std::vector<std::string>::iterator i =
  110. m_IncludeDirectories.begin();
  111. i != m_IncludeDirectories.end(); ++i)
  112. {
  113. std::string path = *i;
  114. path = path + "/";
  115. path = path + cxxFile;
  116. if(cmSystemTools::FileExists(path.c_str()))
  117. {
  118. found = true;
  119. }
  120. }
  121. }
  122. if (!found)
  123. {
  124. cxxFile = root + ".c";
  125. if(cmSystemTools::FileExists(cxxFile.c_str()))
  126. {
  127. found = true;
  128. }
  129. for(std::vector<std::string>::iterator i =
  130. m_IncludeDirectories.begin();
  131. i != m_IncludeDirectories.end(); ++i)
  132. {
  133. std::string path = *i;
  134. path = path + "/";
  135. path = path + cxxFile;
  136. if(cmSystemTools::FileExists(path.c_str()))
  137. {
  138. found = true;
  139. }
  140. }
  141. }
  142. if (found)
  143. {
  144. this->AddDependency(info, cxxFile.c_str());
  145. }
  146. }
  147. }
  148. }
  149. }
  150. // cmOutputRequiredFilesCommand
  151. bool cmOutputRequiredFilesCommand::InitialPass(std::vector<std::string> const& args)
  152. {
  153. if(args.size() != 2 )
  154. {
  155. this->SetError("called with incorrect number of arguments");
  156. return false;
  157. }
  158. // store the arg for final pass
  159. m_File = args[0];
  160. m_OutputFile = args[1];
  161. return true;
  162. }
  163. void cmOutputRequiredFilesCommand::FinalPass()
  164. {
  165. cmTargets &tgts = m_Makefile->GetTargets();
  166. for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
  167. {
  168. l->second.GenerateSourceFilesFromSourceLists(*m_Makefile);
  169. }
  170. // compute the list of files
  171. cmLBDepend md;
  172. md.SetMakefile(m_Makefile);
  173. // find the depends for a file
  174. const cmDependInformation *info = md.FindDependencies(m_File.c_str());
  175. if (info)
  176. {
  177. // write them out
  178. FILE *fout = fopen(m_OutputFile.c_str(),"w");
  179. for(cmDependInformation::DependencySet::const_iterator d =
  180. info->m_DependencySet.begin();
  181. d != info->m_DependencySet.end(); ++d)
  182. {
  183. std::string tmp = (*d)->m_FullPath;
  184. std::string::size_type pos = tmp.rfind('.');
  185. if(pos != std::string::npos && tmp.substr(pos) == ".cxx")
  186. {
  187. tmp = tmp.substr(0, pos);
  188. fprintf(fout,"%s\n",(*d)->m_FullPath.c_str());
  189. }
  190. }
  191. fclose(fout);
  192. }
  193. }