cmGeneratorExpressionDAGChecker.cxx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. }
  96. //----------------------------------------------------------------------------
  97. bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
  98. {
  99. const cmGeneratorExpressionDAGChecker *top = this;
  100. const cmGeneratorExpressionDAGChecker *parent = this->Parent;
  101. while (parent)
  102. {
  103. top = parent;
  104. parent = parent->Parent;
  105. }
  106. const char *prop = top->Property.c_str();
  107. return (strcmp(prop, "LINK_LIBRARIES") == 0
  108. || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
  109. || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
  110. || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 26) == 0
  111. || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 35) == 0);
  112. }
  113. //----------------------------------------------------------------------------
  114. bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories()
  115. {
  116. const char *prop = this->Property.c_str();
  117. return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0
  118. || strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
  119. }
  120. //----------------------------------------------------------------------------
  121. bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions()
  122. {
  123. const char *prop = this->Property.c_str();
  124. return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
  125. || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 );
  126. }