cmCustomCommandGenerator.cxx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmCustomCommandGenerator.h"
  11. #include "cmCustomCommand.h"
  12. #include "cmGeneratorExpression.h"
  13. #include "cmLocalGenerator.h"
  14. #include "cmMakefile.h"
  15. #include "cmOutputConverter.h"
  16. //----------------------------------------------------------------------------
  17. cmCustomCommandGenerator::cmCustomCommandGenerator(
  18. cmCustomCommand const& cc, const std::string& config, cmLocalGenerator* lg):
  19. CC(cc), Config(config), LG(lg),
  20. OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
  21. GE(new cmGeneratorExpression(cc.GetBacktrace())), DependsDone(false)
  22. {
  23. }
  24. //----------------------------------------------------------------------------
  25. cmCustomCommandGenerator::~cmCustomCommandGenerator()
  26. {
  27. delete this->GE;
  28. }
  29. //----------------------------------------------------------------------------
  30. unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
  31. {
  32. return static_cast<unsigned int>(this->CC.GetCommandLines().size());
  33. }
  34. //----------------------------------------------------------------------------
  35. bool cmCustomCommandGenerator::UseCrossCompilingEmulator(unsigned int c) const
  36. {
  37. std::string const& argv0 = this->CC.GetCommandLines()[c][0];
  38. cmGeneratorTarget* target =
  39. this->LG->FindGeneratorTargetToUse(argv0);
  40. if(target && target->GetType() == cmState::EXECUTABLE)
  41. {
  42. return target->GetProperty("CROSSCOMPILING_EMULATOR") != 0;
  43. }
  44. return false;
  45. }
  46. //----------------------------------------------------------------------------
  47. std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
  48. {
  49. std::string const& argv0 = this->CC.GetCommandLines()[c][0];
  50. cmGeneratorTarget* target =
  51. this->LG->FindGeneratorTargetToUse(argv0);
  52. if(target && target->GetType() == cmState::EXECUTABLE &&
  53. (target->IsImported()
  54. || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")))
  55. {
  56. return target->GetLocation(this->Config);
  57. }
  58. if (target && target->GetType() == cmState::EXECUTABLE)
  59. {
  60. const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
  61. if (emulator)
  62. {
  63. return std::string(emulator);
  64. }
  65. }
  66. cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(argv0);
  67. std::string exe = cge->Evaluate(this->LG, this->Config);
  68. return exe;
  69. }
  70. //----------------------------------------------------------------------------
  71. std::string escapeForShellOldStyle(const std::string& str)
  72. {
  73. std::string result;
  74. #if defined(_WIN32) && !defined(__CYGWIN__)
  75. // if there are spaces
  76. std::string temp = str;
  77. if (temp.find(" ") != std::string::npos &&
  78. temp.find("\"")==std::string::npos)
  79. {
  80. result = "\"";
  81. result += str;
  82. result += "\"";
  83. return result;
  84. }
  85. return str;
  86. #else
  87. for(const char* ch = str.c_str(); *ch != '\0'; ++ch)
  88. {
  89. if(*ch == ' ')
  90. {
  91. result += '\\';
  92. }
  93. result += *ch;
  94. }
  95. return result;
  96. #endif
  97. }
  98. //----------------------------------------------------------------------------
  99. void
  100. cmCustomCommandGenerator
  101. ::AppendArguments(unsigned int c, std::string& cmd) const
  102. {
  103. unsigned int offset = 1;
  104. if (this->UseCrossCompilingEmulator(c))
  105. {
  106. offset = 0;
  107. }
  108. cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
  109. for(unsigned int j=offset;j < commandLine.size(); ++j)
  110. {
  111. std::string arg =
  112. this->GE->Parse(commandLine[j])->Evaluate(this->LG,
  113. this->Config);
  114. cmd += " ";
  115. if(this->OldStyle)
  116. {
  117. cmd += escapeForShellOldStyle(arg);
  118. }
  119. else
  120. {
  121. cmOutputConverter converter(this->LG->GetStateSnapshot());
  122. cmd += converter.EscapeForShell(arg, this->MakeVars);
  123. }
  124. }
  125. }
  126. //----------------------------------------------------------------------------
  127. const char* cmCustomCommandGenerator::GetComment() const
  128. {
  129. return this->CC.GetComment();
  130. }
  131. //----------------------------------------------------------------------------
  132. std::string cmCustomCommandGenerator::GetWorkingDirectory() const
  133. {
  134. return this->CC.GetWorkingDirectory();
  135. }
  136. //----------------------------------------------------------------------------
  137. std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
  138. {
  139. return this->CC.GetOutputs();
  140. }
  141. //----------------------------------------------------------------------------
  142. std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
  143. {
  144. return this->CC.GetByproducts();
  145. }
  146. //----------------------------------------------------------------------------
  147. std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
  148. {
  149. if (!this->DependsDone)
  150. {
  151. this->DependsDone = true;
  152. std::vector<std::string> depends = this->CC.GetDepends();
  153. for(std::vector<std::string>::const_iterator
  154. i = depends.begin();
  155. i != depends.end(); ++i)
  156. {
  157. cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
  158. = this->GE->Parse(*i);
  159. std::vector<std::string> result;
  160. cmSystemTools::ExpandListArgument(
  161. cge->Evaluate(this->LG, this->Config), result);
  162. for (std::vector<std::string>::iterator it = result.begin();
  163. it != result.end(); ++it)
  164. {
  165. if (cmSystemTools::FileIsFullPath(it->c_str()))
  166. {
  167. *it = cmSystemTools::CollapseFullPath(*it);
  168. }
  169. }
  170. this->Depends.insert(this->Depends.end(), result.begin(), result.end());
  171. }
  172. }
  173. return this->Depends;
  174. }