cmAddCustomCommandCommand.cxx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 "cmAddCustomCommandCommand.h"
  14. #include "cmTarget.h"
  15. // cmAddCustomCommandCommand
  16. bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args)
  17. {
  18. /* Let's complain at the end of this function about the lack of a particular
  19. arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
  20. are required.
  21. */
  22. if (args.size() < 4)
  23. {
  24. this->SetError("called with wrong number of arguments.");
  25. return false;
  26. }
  27. std::string source, target, comment, output, main_dependency;
  28. std::vector<std::string> depends, outputs;
  29. // Accumulate one command line at a time.
  30. cmCustomCommandLine currentLine;
  31. // Save all command lines.
  32. cmCustomCommandLines commandLines;
  33. cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
  34. enum tdoing {
  35. doing_source,
  36. doing_command,
  37. doing_target,
  38. doing_depends,
  39. doing_main_dependency,
  40. doing_output,
  41. doing_outputs,
  42. doing_comment,
  43. doing_nothing
  44. };
  45. tdoing doing = doing_nothing;
  46. for (unsigned int j = 0; j < args.size(); ++j)
  47. {
  48. std::string const& copy = args[j];
  49. if(copy == "SOURCE")
  50. {
  51. doing = doing_source;
  52. }
  53. else if(copy == "COMMAND")
  54. {
  55. doing = doing_command;
  56. // Save the current command before starting the next command.
  57. if(!currentLine.empty())
  58. {
  59. commandLines.push_back(currentLine);
  60. currentLine.clear();
  61. }
  62. }
  63. else if(copy == "PRE_BUILD")
  64. {
  65. cctype = cmTarget::PRE_BUILD;
  66. }
  67. else if(copy == "PRE_LINK")
  68. {
  69. cctype = cmTarget::PRE_LINK;
  70. }
  71. else if(copy == "POST_BUILD")
  72. {
  73. cctype = cmTarget::POST_BUILD;
  74. }
  75. else if(copy == "TARGET")
  76. {
  77. doing = doing_target;
  78. }
  79. else if(copy == "ARGS")
  80. {
  81. // Ignore this old keyword.
  82. }
  83. else if (copy == "DEPENDS")
  84. {
  85. doing = doing_depends;
  86. }
  87. else if (copy == "OUTPUTS")
  88. {
  89. doing = doing_outputs;
  90. }
  91. else if (copy == "OUTPUT")
  92. {
  93. doing = doing_output;
  94. }
  95. else if (copy == "MAIN_DEPENDENCY")
  96. {
  97. doing = doing_main_dependency;
  98. }
  99. else if (copy == "COMMENT")
  100. {
  101. doing = doing_comment;
  102. }
  103. else
  104. {
  105. switch (doing)
  106. {
  107. case doing_source:
  108. source = copy;
  109. break;
  110. case doing_output:
  111. output = copy;
  112. break;
  113. case doing_main_dependency:
  114. main_dependency = copy;
  115. break;
  116. case doing_command:
  117. currentLine.push_back(copy);
  118. break;
  119. case doing_target:
  120. target = copy;
  121. break;
  122. case doing_depends:
  123. depends.push_back(copy);
  124. break;
  125. case doing_outputs:
  126. outputs.push_back(copy);
  127. break;
  128. case doing_comment:
  129. comment = copy;
  130. break;
  131. default:
  132. this->SetError("Wrong syntax. Unknown type of argument.");
  133. return false;
  134. }
  135. }
  136. }
  137. // Store the last command line finished.
  138. if(!currentLine.empty())
  139. {
  140. commandLines.push_back(currentLine);
  141. currentLine.clear();
  142. }
  143. // At this point we could complain about the lack of arguments. For
  144. // the moment, let's say that COMMAND, TARGET are always required.
  145. if(output.empty() && target.empty())
  146. {
  147. this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
  148. return false;
  149. }
  150. if(source.empty() && !target.empty() && !output.empty())
  151. {
  152. this->SetError("Wrong syntax. A TARGET and OUTPUT can not both be specified.");
  153. return false;
  154. }
  155. // Choose which mode of the command to use.
  156. if(source.empty() && output.empty())
  157. {
  158. // Source is empty, use the target.
  159. std::vector<std::string> no_depends;
  160. m_Makefile->AddCustomCommandToTarget(target.c_str(), no_depends,
  161. commandLines, cctype,
  162. comment.c_str());
  163. }
  164. else if(target.empty())
  165. {
  166. // Target is empty, use the output.
  167. m_Makefile->AddCustomCommandToOutput(output.c_str(), depends,
  168. main_dependency.c_str(),
  169. commandLines, comment.c_str());
  170. }
  171. else
  172. {
  173. // Use the old-style mode for backward compatibility.
  174. m_Makefile->AddCustomCommandOldStyle(target.c_str(), outputs, depends,
  175. source.c_str(), commandLines,
  176. comment.c_str());
  177. }
  178. return true;
  179. }