cmNinjaUtilityTargetGenerator.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2011 Peter Collingbourne <[email protected]>
  4. Copyright 2011 Nicolas Despres <[email protected]>
  5. Distributed under the OSI-approved BSD License (the "License");
  6. see accompanying file Copyright.txt for details.
  7. This software is distributed WITHOUT ANY WARRANTY; without even the
  8. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. See the License for more information.
  10. ============================================================================*/
  11. #include "cmNinjaUtilityTargetGenerator.h"
  12. #include "cmCustomCommand.h"
  13. #include "cmGeneratedFileStream.h"
  14. #include "cmGlobalNinjaGenerator.h"
  15. #include "cmMakefile.h"
  16. #include "cmSourceFile.h"
  17. #include "cmTarget.h"
  18. cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
  19. cmGeneratorTarget *target)
  20. : cmNinjaTargetGenerator(target->Target) {}
  21. cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {}
  22. void cmNinjaUtilityTargetGenerator::Generate()
  23. {
  24. std::vector<std::string> commands;
  25. cmNinjaDeps deps, outputs;
  26. const std::vector<cmCustomCommand> *cmdLists[2] = {
  27. &this->GetTarget()->GetPreBuildCommands(),
  28. &this->GetTarget()->GetPostBuildCommands()
  29. };
  30. for (unsigned i = 0; i != 2; ++i) {
  31. for (std::vector<cmCustomCommand>::const_iterator
  32. ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
  33. this->GetLocalGenerator()->AppendCustomCommandDeps(&*ci, deps);
  34. this->GetLocalGenerator()->AppendCustomCommandLines(&*ci, commands);
  35. }
  36. }
  37. std::vector<cmSourceFile*> sources;
  38. this->GetTarget()->GetSourceFiles(sources);
  39. for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
  40. source != sources.end(); ++source)
  41. {
  42. if(cmCustomCommand* cc = (*source)->GetCustomCommand())
  43. {
  44. this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
  45. // Depend on all custom command outputs.
  46. const std::vector<std::string>& ccOutputs = cc->GetOutputs();
  47. std::transform(ccOutputs.begin(), ccOutputs.end(),
  48. std::back_inserter(deps), MapToNinjaPath());
  49. }
  50. }
  51. this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
  52. this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), deps);
  53. if (commands.empty()) {
  54. this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
  55. "Utility command for "
  56. + this->GetTargetName(),
  57. outputs,
  58. deps);
  59. } else {
  60. std::string command =
  61. this->GetLocalGenerator()->BuildCommandLine(commands);
  62. const char *echoStr = this->GetTarget()->GetProperty("EchoString");
  63. std::string desc;
  64. if (echoStr)
  65. desc = echoStr;
  66. else
  67. desc = "Running utility command for " + this->GetTargetName();
  68. // TODO: fix problematic global targets. For now, search and replace the
  69. // makefile vars.
  70. cmSystemTools::ReplaceString(
  71. command,
  72. "$(CMAKE_SOURCE_DIR)",
  73. this->GetLocalGenerator()->ConvertToOutputFormat(
  74. this->GetTarget()->GetMakefile()->GetHomeDirectory(),
  75. cmLocalGenerator::SHELL).c_str());
  76. cmSystemTools::ReplaceString(
  77. command,
  78. "$(CMAKE_BINARY_DIR)",
  79. this->GetLocalGenerator()->ConvertToOutputFormat(
  80. this->GetTarget()->GetMakefile()->GetHomeOutputDirectory(),
  81. cmLocalGenerator::SHELL).c_str());
  82. cmSystemTools::ReplaceString(command, "$(ARGS)", "");
  83. if (command.find('$') != std::string::npos)
  84. return;
  85. std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
  86. utilCommandName += this->GetTargetName() + ".util";
  87. this->GetGlobalGenerator()->WriteCustomCommandBuild(
  88. command,
  89. desc,
  90. "Utility command for " + this->GetTargetName(),
  91. cmNinjaDeps(1, utilCommandName),
  92. deps);
  93. this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
  94. "",
  95. outputs,
  96. cmNinjaDeps(1, utilCommandName)
  97. );
  98. }
  99. this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
  100. this->GetTarget());
  101. }