cmGeneratorExpressionDAGChecker.cxx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2012 Stephen Kelly <[email protected]>
  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 "cmGeneratorExpressionDAGChecker.h"
  11. #include "cmMakefile.h"
  12. //----------------------------------------------------------------------------
  13. cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
  14. const cmListFileBacktrace &backtrace,
  15. const std::string &target,
  16. const std::string &property,
  17. const GeneratorExpressionContent *content,
  18. cmGeneratorExpressionDAGChecker *parent)
  19. : Parent(parent), Target(target), Property(property),
  20. Content(content), Backtrace(backtrace)
  21. {
  22. this->CheckResult = this->checkGraph();
  23. }
  24. //----------------------------------------------------------------------------
  25. cmGeneratorExpressionDAGChecker::Result
  26. cmGeneratorExpressionDAGChecker::check() const
  27. {
  28. return this->CheckResult;
  29. }
  30. //----------------------------------------------------------------------------
  31. void cmGeneratorExpressionDAGChecker::reportError(
  32. cmGeneratorExpressionContext *context,
  33. const std::string &expr)
  34. {
  35. if (this->CheckResult == DAG)
  36. {
  37. return;
  38. }
  39. context->HadError = true;
  40. if (context->Quiet)
  41. {
  42. return;
  43. }
  44. const cmGeneratorExpressionDAGChecker *parent = this->Parent;
  45. if (parent && !parent->Parent)
  46. {
  47. cmOStringStream e;
  48. e << "Error evaluating generator expression:\n"
  49. << " " << expr << "\n"
  50. << "Self reference on target \""
  51. << context->HeadTarget->GetName() << "\".\n";
  52. context->Makefile->GetCMakeInstance()
  53. ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
  54. parent->Backtrace);
  55. return;
  56. }
  57. {
  58. cmOStringStream e;
  59. e << "Error evaluating generator expression:\n"
  60. << " " << expr << "\n"
  61. << "Dependency loop found.";
  62. context->Makefile->GetCMakeInstance()
  63. ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
  64. context->Backtrace);
  65. }
  66. int loopStep = 1;
  67. while (parent)
  68. {
  69. cmOStringStream e;
  70. e << "Loop step " << loopStep << "\n"
  71. << " "
  72. << (parent->Content ? parent->Content->GetOriginalExpression() : expr)
  73. << "\n";
  74. context->Makefile->GetCMakeInstance()
  75. ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
  76. parent->Backtrace);
  77. parent = parent->Parent;
  78. ++loopStep;
  79. }
  80. }
  81. //----------------------------------------------------------------------------
  82. cmGeneratorExpressionDAGChecker::Result
  83. cmGeneratorExpressionDAGChecker::checkGraph() const
  84. {
  85. const cmGeneratorExpressionDAGChecker *parent = this->Parent;
  86. while (parent)
  87. {
  88. if (this->Target == parent->Target && this->Property == parent->Property)
  89. {
  90. return parent->Parent ? CYCLIC_REFERENCE : SELF_REFERENCE;
  91. }
  92. parent = parent->Parent;
  93. }
  94. return DAG;
  95. }