cmITKWrapTclCommand.cxx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html 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 "cmITKWrapTclCommand.h"
  14. #include "cmMakeDepend.h"
  15. cmITKWrapTclCommand::cmITKWrapTclCommand():
  16. m_MakeDepend(new cmMakeDepend)
  17. {
  18. }
  19. cmITKWrapTclCommand::~cmITKWrapTclCommand()
  20. {
  21. delete m_MakeDepend;
  22. }
  23. void
  24. cmITKWrapTclCommand::AddDependencies(cmDependInformation const *info,
  25. std::vector<std::string>& depends,
  26. std::set<cmDependInformation const*>& visited)
  27. {
  28. if(!info)
  29. {
  30. return;
  31. }
  32. // add info to the visited set
  33. visited.insert(info);
  34. // add this dependency and the recurse
  35. // now recurse with info's dependencies
  36. for(cmDependInformation::DependencySet::const_iterator d =
  37. info->m_DependencySet.begin();
  38. d != info->m_DependencySet.end(); ++d)
  39. {
  40. if (visited.find(*d) == visited.end())
  41. {
  42. if((*d)->m_FullPath != "")
  43. {
  44. depends.push_back((*d)->m_FullPath);
  45. }
  46. this->AddDependencies(*d,depends,visited);
  47. }
  48. }
  49. }
  50. // cmITKWrapTclCommand
  51. bool cmITKWrapTclCommand::InitialPass(std::vector<std::string> const& args)
  52. {
  53. if(args.size() < 2 )
  54. {
  55. this->SetError("called with incorrect number of arguments");
  56. return false;
  57. }
  58. // keep the target name
  59. m_TargetName = args[0];
  60. m_Target = &m_Makefile->GetTargets()[m_TargetName.c_str()];
  61. // Prepare the dependency generator.
  62. m_MakeDepend->SetMakefile(m_Makefile);
  63. for(std::vector<std::string>::const_iterator i = (args.begin() + 1);
  64. i != args.end(); ++i)
  65. {
  66. if(!this->CreateCableRule((*i).c_str())) { return false; }
  67. }
  68. return true;
  69. }
  70. bool cmITKWrapTclCommand::CreateCableRule(const char* configFile)
  71. {
  72. std::string tclFile =
  73. cmSystemTools::GetFilenameWithoutExtension(configFile);
  74. tclFile += "_tcl";
  75. std::string inFile = m_Makefile->GetCurrentDirectory();
  76. inFile += "/";
  77. inFile += configFile;
  78. std::string outDir = m_Makefile->GetCurrentOutputDirectory();
  79. // Generate the rule to run cable to generate wrappers.
  80. std::string command = this->GetCableFromCache();
  81. std::vector<std::string> depends;
  82. // Special case for CMake's wrapping test. Don't add dependency if
  83. // it is a dummy executable.
  84. if(command != "echo")
  85. {
  86. depends.push_back(command);
  87. }
  88. std::vector<std::string> commandArgs;
  89. commandArgs.push_back(inFile);
  90. commandArgs.push_back("-tcl");
  91. std::string tmp = tclFile+".cxx";
  92. commandArgs.push_back(tmp);
  93. #if !defined(_WIN32) || defined(__CYGWIN__)
  94. tmp = "${CMAKE_CXX_COMPILER}";
  95. m_Makefile->ExpandVariablesInString(tmp);
  96. if(tmp.length() > 0)
  97. {
  98. commandArgs.push_back("--gccxml-compiler");
  99. commandArgs.push_back(tmp);
  100. tmp = "${CMAKE_CXX_FLAGS}";
  101. m_Makefile->ExpandVariablesInString(tmp);
  102. commandArgs.push_back("--gccxml-cxxflags");
  103. commandArgs.push_back(tmp);
  104. }
  105. #else
  106. const char* genName = m_Makefile->GetDefinition("CMAKE_GENERATOR");
  107. if (genName)
  108. {
  109. std::string gen = genName;
  110. if(gen == "Visual Studio 6")
  111. {
  112. commandArgs.push_back("--gccxml-compiler");
  113. commandArgs.push_back("msvc6");
  114. tmp = "${CMAKE_CXX_FLAGS}";
  115. m_Makefile->ExpandVariablesInString(tmp);
  116. commandArgs.push_back("--gccxml-cxxflags");
  117. commandArgs.push_back(tmp);
  118. }
  119. else if(gen == "Visual Studio 7")
  120. {
  121. commandArgs.push_back("--gccxml-compiler");
  122. commandArgs.push_back("msvc7");
  123. tmp = "${CMAKE_CXX_FLAGS}";
  124. m_Makefile->ExpandVariablesInString(tmp);
  125. commandArgs.push_back("--gccxml-cxxflags");
  126. commandArgs.push_back(tmp);
  127. }
  128. else if(gen == "NMake Makefiles")
  129. {
  130. tmp = "${CMAKE_CXX_COMPILER}";
  131. m_Makefile->ExpandVariablesInString(tmp);
  132. commandArgs.push_back("--gccxml-compiler");
  133. commandArgs.push_back(tmp);
  134. tmp = "${CMAKE_CXX_FLAGS}";
  135. m_Makefile->ExpandVariablesInString(tmp);
  136. commandArgs.push_back("--gccxml-cxxflags");
  137. commandArgs.push_back(tmp);
  138. }
  139. }
  140. #endif
  141. const char* gccxml = m_Makefile->GetDefinition("ITK_GCCXML_EXECUTABLE");
  142. if(gccxml)
  143. {
  144. commandArgs.push_back("--gccxml");
  145. commandArgs.push_back(gccxml);
  146. }
  147. tmp = "-I";
  148. tmp += m_Makefile->GetStartDirectory();
  149. commandArgs.push_back(tmp);
  150. const std::vector<std::string>& includes =
  151. m_Makefile->GetIncludeDirectories();
  152. for(std::vector<std::string>::const_iterator i = includes.begin();
  153. i != includes.end(); ++i)
  154. {
  155. tmp = "-I";
  156. tmp += i->c_str();
  157. m_Makefile->ExpandVariablesInString(tmp);
  158. commandArgs.push_back(tmp);
  159. }
  160. // Get the dependencies.
  161. const cmDependInformation* info =
  162. m_MakeDepend->FindDependencies(inFile.c_str());
  163. if (info)
  164. {
  165. std::set<cmDependInformation const*> visited;
  166. this->AddDependencies(info, depends, visited);
  167. }
  168. std::string output;
  169. output = outDir+"/"+tclFile+".cxx";
  170. // Add the source to the makefile.
  171. cmSourceFile file;
  172. file.SetName(tclFile.c_str(), outDir.c_str(), "cxx", false);
  173. // Set dependency hints.
  174. file.GetDepends().push_back(inFile.c_str());
  175. file.GetDepends().push_back("CableTclFacility/ctCalls.h");
  176. m_Makefile->AddSource(file);
  177. m_Makefile->AddCustomCommandToOutput(output.c_str(),
  178. command.c_str(),
  179. commandArgs,
  180. inFile.c_str(),
  181. depends);
  182. // Add the generated source to the package's source list.
  183. m_Target->GetSourceLists().push_back(output);
  184. return true;
  185. }
  186. /**
  187. * Get the "CABLE" cache entry value. If there is no cache entry for CABLE,
  188. * one will be created and initialized to NOTFOUND.
  189. */
  190. std::string cmITKWrapTclCommand::GetCableFromCache() const
  191. {
  192. const char* cable =
  193. m_Makefile->GetDefinition("CABLE");
  194. if(cable)
  195. { return cable; }
  196. m_Makefile->AddCacheDefinition("CABLE",
  197. "CABLE-NOTFOUND",
  198. "Path to CABLE executable.",
  199. cmCacheManager::FILEPATH);
  200. return "CABLE-NOTFOUND";
  201. }