cmCustomCommandGenerator.cxx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
  17. const std::string& config,
  18. cmLocalGenerator* lg)
  19. : CC(cc)
  20. , Config(config)
  21. , LG(lg)
  22. , OldStyle(cc.GetEscapeOldStyle())
  23. , MakeVars(cc.GetEscapeAllowMakeVars())
  24. , GE(new cmGeneratorExpression(cc.GetBacktrace()))
  25. , DependsDone(false)
  26. {
  27. }
  28. cmCustomCommandGenerator::~cmCustomCommandGenerator()
  29. {
  30. delete this->GE;
  31. }
  32. unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
  33. {
  34. return static_cast<unsigned int>(this->CC.GetCommandLines().size());
  35. }
  36. bool cmCustomCommandGenerator::UseCrossCompilingEmulator(unsigned int c) const
  37. {
  38. std::string const& argv0 = this->CC.GetCommandLines()[c][0];
  39. cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
  40. if (target && target->GetType() == cmState::EXECUTABLE) {
  41. return target->GetProperty("CROSSCOMPILING_EMULATOR") != CM_NULLPTR;
  42. }
  43. return false;
  44. }
  45. std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
  46. {
  47. std::string const& argv0 = this->CC.GetCommandLines()[c][0];
  48. cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
  49. if (target && target->GetType() == cmState::EXECUTABLE &&
  50. (target->IsImported() ||
  51. !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) {
  52. return target->GetLocation(this->Config);
  53. }
  54. if (target && target->GetType() == cmState::EXECUTABLE) {
  55. const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
  56. if (emulator) {
  57. return std::string(emulator);
  58. }
  59. }
  60. cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(argv0);
  61. std::string exe = cge->Evaluate(this->LG, this->Config);
  62. return exe;
  63. }
  64. std::string escapeForShellOldStyle(const std::string& str)
  65. {
  66. std::string result;
  67. #if defined(_WIN32) && !defined(__CYGWIN__)
  68. // if there are spaces
  69. std::string temp = str;
  70. if (temp.find(" ") != std::string::npos &&
  71. temp.find("\"") == std::string::npos) {
  72. result = "\"";
  73. result += str;
  74. result += "\"";
  75. return result;
  76. }
  77. return str;
  78. #else
  79. for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
  80. if (*ch == ' ') {
  81. result += '\\';
  82. }
  83. result += *ch;
  84. }
  85. return result;
  86. #endif
  87. }
  88. void cmCustomCommandGenerator::AppendArguments(unsigned int c,
  89. std::string& cmd) const
  90. {
  91. unsigned int offset = 1;
  92. if (this->UseCrossCompilingEmulator(c)) {
  93. offset = 0;
  94. }
  95. cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
  96. for (unsigned int j = offset; j < commandLine.size(); ++j) {
  97. std::string arg =
  98. this->GE->Parse(commandLine[j])->Evaluate(this->LG, this->Config);
  99. cmd += " ";
  100. if (this->OldStyle) {
  101. cmd += escapeForShellOldStyle(arg);
  102. } else {
  103. cmOutputConverter converter(this->LG->GetStateSnapshot());
  104. cmd += converter.EscapeForShell(arg, this->MakeVars);
  105. }
  106. }
  107. }
  108. const char* cmCustomCommandGenerator::GetComment() const
  109. {
  110. return this->CC.GetComment();
  111. }
  112. std::string cmCustomCommandGenerator::GetWorkingDirectory() const
  113. {
  114. return this->CC.GetWorkingDirectory();
  115. }
  116. std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
  117. {
  118. return this->CC.GetOutputs();
  119. }
  120. std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
  121. {
  122. return this->CC.GetByproducts();
  123. }
  124. std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
  125. {
  126. if (!this->DependsDone) {
  127. this->DependsDone = true;
  128. std::vector<std::string> depends = this->CC.GetDepends();
  129. for (std::vector<std::string>::const_iterator i = depends.begin();
  130. i != depends.end(); ++i) {
  131. cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(*i);
  132. std::vector<std::string> result;
  133. cmSystemTools::ExpandListArgument(cge->Evaluate(this->LG, this->Config),
  134. result);
  135. for (std::vector<std::string>::iterator it = result.begin();
  136. it != result.end(); ++it) {
  137. if (cmSystemTools::FileIsFullPath(it->c_str())) {
  138. *it = cmSystemTools::CollapseFullPath(*it);
  139. }
  140. }
  141. this->Depends.insert(this->Depends.end(), result.begin(), result.end());
  142. }
  143. }
  144. return this->Depends;
  145. }