cmCustomCommandGenerator.cxx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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 "cmMakefile.h"
  12. #include "cmLocalGenerator.h"
  13. #include "cmCustomCommand.h"
  14. #include "cmOutputConverter.h"
  15. #include "cmGeneratorExpression.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. std::string cmCustomCommandGenerator::GetCommand(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. (target->IsImported()
  42. || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")))
  43. {
  44. return target->GetLocation(this->Config);
  45. }
  46. return this->GE->Parse(argv0)->Evaluate(this->LG, this->Config);
  47. }
  48. //----------------------------------------------------------------------------
  49. std::string escapeForShellOldStyle(const std::string& str)
  50. {
  51. std::string result;
  52. #if defined(_WIN32) && !defined(__CYGWIN__)
  53. // if there are spaces
  54. std::string temp = str;
  55. if (temp.find(" ") != std::string::npos &&
  56. temp.find("\"")==std::string::npos)
  57. {
  58. result = "\"";
  59. result += str;
  60. result += "\"";
  61. return result;
  62. }
  63. return str;
  64. #else
  65. for(const char* ch = str.c_str(); *ch != '\0'; ++ch)
  66. {
  67. if(*ch == ' ')
  68. {
  69. result += '\\';
  70. }
  71. result += *ch;
  72. }
  73. return result;
  74. #endif
  75. }
  76. //----------------------------------------------------------------------------
  77. void
  78. cmCustomCommandGenerator
  79. ::AppendArguments(unsigned int c, std::string& cmd) const
  80. {
  81. cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
  82. for(unsigned int j=1;j < commandLine.size(); ++j)
  83. {
  84. std::string arg =
  85. this->GE->Parse(commandLine[j])->Evaluate(this->LG,
  86. this->Config);
  87. cmd += " ";
  88. if(this->OldStyle)
  89. {
  90. cmd += escapeForShellOldStyle(arg);
  91. }
  92. else
  93. {
  94. cmOutputConverter converter(this->LG->GetStateSnapshot());
  95. cmd += converter.EscapeForShell(arg, this->MakeVars);
  96. }
  97. }
  98. }
  99. //----------------------------------------------------------------------------
  100. const char* cmCustomCommandGenerator::GetComment() const
  101. {
  102. return this->CC.GetComment();
  103. }
  104. //----------------------------------------------------------------------------
  105. std::string cmCustomCommandGenerator::GetWorkingDirectory() const
  106. {
  107. return this->CC.GetWorkingDirectory();
  108. }
  109. //----------------------------------------------------------------------------
  110. std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
  111. {
  112. return this->CC.GetOutputs();
  113. }
  114. //----------------------------------------------------------------------------
  115. std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
  116. {
  117. return this->CC.GetByproducts();
  118. }
  119. //----------------------------------------------------------------------------
  120. std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
  121. {
  122. if (!this->DependsDone)
  123. {
  124. this->DependsDone = true;
  125. std::vector<std::string> depends = this->CC.GetDepends();
  126. for(std::vector<std::string>::const_iterator
  127. i = depends.begin();
  128. i != depends.end(); ++i)
  129. {
  130. cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
  131. = this->GE->Parse(*i);
  132. std::vector<std::string> result;
  133. cmSystemTools::ExpandListArgument(
  134. cge->Evaluate(this->LG, this->Config), result);
  135. for (std::vector<std::string>::iterator it = result.begin();
  136. it != result.end(); ++it)
  137. {
  138. if (cmSystemTools::FileIsFullPath(it->c_str()))
  139. {
  140. *it = cmSystemTools::CollapseFullPath(*it);
  141. }
  142. }
  143. this->Depends.insert(this->Depends.end(), result.begin(), result.end());
  144. }
  145. }
  146. return this->Depends;
  147. }