cmConfigureGccXmlCommand.cxx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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 "cmConfigureGccXmlCommand.h"
  14. #include "cmCacheManager.h"
  15. cmConfigureGccXmlCommand::cmConfigureGccXmlCommand()
  16. {
  17. }
  18. cmConfigureGccXmlCommand::~cmConfigureGccXmlCommand()
  19. {
  20. }
  21. // cmConfigureGccXmlCommand
  22. bool cmConfigureGccXmlCommand::InitialPass(std::vector<std::string> const& args)
  23. {
  24. if(args.size() != 2)
  25. {
  26. this->SetError("called with incorrect number of arguments");
  27. return false;
  28. }
  29. // If the cache entry already exists, we are done.
  30. std::string cacheName = args[1];
  31. const char* cacheValue =
  32. m_Makefile->GetDefinition(cacheName.c_str());
  33. if(cacheValue && (std::string(cacheValue) != ""))
  34. { return true; }
  35. // Get the gccxml support directory location. This is based on the
  36. // executable location.
  37. if(!this->GetSupportDirectory(args[0].c_str()))
  38. { return false; }
  39. #if defined(_WIN32) && !defined(__CYGWIN__)
  40. // On Windows, we will just look at VcInclude/FLAGS.txt for now.
  41. if(!this->FindVcIncludeFlags())
  42. { return false; }
  43. #else
  44. // On UNIX, we have to determine which compiler is being used, and
  45. // attempt to use that compiler's support directory.
  46. if(this->CompilerIsGCC())
  47. {
  48. if(!this->FindGccIncludeFlags())
  49. { return false; }
  50. }
  51. else if(this->CompilerIsMipsPro())
  52. {
  53. if(!this->FindMproIncludeFlags())
  54. { return false; }
  55. }
  56. else
  57. {
  58. this->SetError("Compiler is not supported by GCC-XML!\n");
  59. return false;
  60. }
  61. #endif
  62. // Add the cache entry with the flags found.
  63. m_Makefile->AddCacheDefinition(
  64. cacheName.c_str(),
  65. m_Flags.c_str(),
  66. "Flags to GCC-XML to get it to parse the native compiler's headers.",
  67. cmCacheManager::STRING);
  68. return true;
  69. }
  70. /**
  71. * Given the location of the GCC-XML executable, find the root of the
  72. * support library tree. Subdirectories of the returned location should
  73. * contain the compiler-specific support libraries.
  74. */
  75. bool cmConfigureGccXmlCommand::GetSupportDirectory(const char* exeLoc)
  76. {
  77. std::string gccxml = exeLoc;
  78. m_Makefile->ExpandVariablesInString(gccxml);
  79. if(!cmSystemTools::FileExists(gccxml.c_str()))
  80. {
  81. std::string err = "Can't find GCC-XML at given path: ";
  82. err += gccxml;
  83. this->SetError(err.c_str());
  84. return false;
  85. }
  86. std::string dir;
  87. std::string file;
  88. // Get the directory (also converts to unix slashes).
  89. cmSystemTools::SplitProgramPath(gccxml.c_str(), dir, file);
  90. #if !defined(_WIN32) || defined(__CYGWIN__)
  91. // On UNIX platforms, we must replace the "/bin" suffix with
  92. // "/share/GCC_XML". If there is no "/bin" suffix, we will assume
  93. // that the user has put everything in one directory, and not change
  94. // the path.
  95. if(dir.substr(dir.length()-4, 4) == "/bin")
  96. {
  97. dir = dir.substr(0, dir.length()-4) + "/share/GCC_XML";
  98. }
  99. #endif
  100. m_SupportDir = dir;
  101. return true;
  102. }
  103. /**
  104. * Find the flags needed to use the Visual C++ support library.
  105. */
  106. bool cmConfigureGccXmlCommand::FindVcIncludeFlags()
  107. {
  108. std::string fname = m_SupportDir+"/VcInclude/FLAGS.txt";
  109. std::ifstream flagsFile(fname.c_str());
  110. if(!flagsFile)
  111. {
  112. std::string err = "Cannot open GCC-XML flags file \""+fname+"\".";
  113. this->SetError(err.c_str());
  114. return false;
  115. }
  116. // TODO: Replace this with a real implementation.
  117. char buf[4096];
  118. flagsFile.getline(buf, 4096);
  119. if(!flagsFile)
  120. {
  121. std::string err = "Error reading from GCC-XML flags file \""+fname+"\".";
  122. this->SetError(err.c_str());
  123. return false;
  124. }
  125. m_Flags = buf;
  126. return true;
  127. }
  128. /**
  129. * Find the flags needed to use the GCC support library.
  130. */
  131. bool cmConfigureGccXmlCommand::FindGccIncludeFlags()
  132. {
  133. std::string supportDir = m_SupportDir+"/GccInclude";
  134. if(!cmSystemTools::FileIsDirectory(supportDir.c_str()))
  135. {
  136. std::string err = "No GCC support library for GCC-XML. Couldn't find directory \""+supportDir+"\".";
  137. this->SetError(err.c_str());
  138. return false;
  139. }
  140. // Try to run the find_gcc_options command.
  141. std::string command = supportDir+"/find_gcc_options";
  142. std::string flags;
  143. if(!cmSystemTools::RunCommand(command.c_str(), flags))
  144. {
  145. this->SetError("Could not run find_gcc_options!");
  146. return false;
  147. }
  148. // Strip newline from end of flags.
  149. if((flags.length() > 0)
  150. && (flags[flags.length()-1] == '\n'))
  151. {
  152. flags = flags.substr(0, flags.length()-1);
  153. if((flags.length() > 0)
  154. && (flags[flags.length()-1] == '\r'))
  155. {
  156. flags = flags.substr(0, flags.length()-1);
  157. }
  158. }
  159. // Use the result of the command as the flags.
  160. m_Flags = flags;
  161. return true;
  162. }
  163. /**
  164. * Find the flags needed to use the MIPSpro support library.
  165. */
  166. bool cmConfigureGccXmlCommand::FindMproIncludeFlags()
  167. {
  168. std::string supportDir = m_SupportDir+"/MproInclude";
  169. if(!cmSystemTools::FileIsDirectory(supportDir.c_str()))
  170. {
  171. std::string err = "No MIPSpro support library for GCC-XML. Couldn't find directory \""+supportDir+"\".";
  172. this->SetError(err.c_str());
  173. return false;
  174. }
  175. // Try to run the find_mpro_options command.
  176. std::string command = supportDir+"/find_mpro_options";
  177. std::string flags;
  178. if(!cmSystemTools::RunCommand(command.c_str(), flags))
  179. {
  180. this->SetError("Could not run find_mpro_options!");
  181. return false;
  182. }
  183. // Strip newline from end of flags.
  184. if((flags.length() > 0)
  185. && (flags[flags.length()-1] == '\n'))
  186. {
  187. flags = flags.substr(0, flags.length()-1);
  188. if((flags.length() > 0)
  189. && (flags[flags.length()-1] == '\r'))
  190. {
  191. flags = flags.substr(0, flags.length()-1);
  192. }
  193. }
  194. // Use the result of the command as the flags.
  195. m_Flags = flags;
  196. return true;
  197. }
  198. /**
  199. * Determine whether the compiler is GCC.
  200. */
  201. bool cmConfigureGccXmlCommand::CompilerIsGCC() const
  202. {
  203. const char* isGNU = m_Makefile->GetDefinition("CMAKE_COMPILER_IS_GNUCXX");
  204. return (isGNU && !cmSystemTools::IsOff(isGNU));
  205. }
  206. /**
  207. * Determine whether the compiler is MipsPro.
  208. */
  209. bool cmConfigureGccXmlCommand::CompilerIsMipsPro() const
  210. {
  211. const char* compiler = m_Makefile->GetDefinition("CMAKE_CXX_COMPILER");
  212. if(!compiler) { return false; }
  213. std::string command = compiler;
  214. command += " -version 2>&1";
  215. std::string output;
  216. if(!cmSystemTools::RunCommand(command.c_str(), output, false))
  217. { return false; }
  218. if(output.find("MIPSpro") != std::string::npos)
  219. {
  220. return true;
  221. }
  222. return false;
  223. }