Make cycles in target properties ignored, not an error.

Constructs such as these are an error as they are direct self-references:

 set_property(TARGET foo APPEND PROPERTY
   INCLUDE_DIRECTORIES $<TARGET_PROPERTY:foo,INCLUDE_DIRECTORIES>)
 set_property(TARGET foo APPEND PROPERTY
   INCLUDE_DIRECTORIES $<TARGET_PROPERTY:INCLUDE_DIRECTORIES>)

However, this is an indirect self-reference in a cycle, and not an error:

 set_property(TARGET foo APPEND PROPERTY
   INCLUDE_DIRECTORIES $<TARGET_PROPERTY:bar,INCLUDE_DIRECTORIES>)
 set_property(TARGET bar APPEND PROPERTY
   INCLUDE_DIRECTORIES $<TARGET_PROPERTY:foo,INCLUDE_DIRECTORIES>)
This commit is contained in:
Stephen Kelly 2012-12-21 15:49:19 +01:00
parent d0f950fdba
commit c67b8124f7
3 changed files with 25 additions and 11 deletions

View File

@ -24,13 +24,14 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
: Parent(parent), Target(target), Property(property),
Content(content), Backtrace(backtrace)
{
this->IsDAG = this->isDAG();
this->CheckResult = this->checkGraph();
}
//----------------------------------------------------------------------------
bool cmGeneratorExpressionDAGChecker::check() const
cmGeneratorExpressionDAGChecker::Result
cmGeneratorExpressionDAGChecker::check() const
{
return this->IsDAG;
return this->CheckResult;
}
//----------------------------------------------------------------------------
@ -38,7 +39,7 @@ void cmGeneratorExpressionDAGChecker::reportError(
cmGeneratorExpressionContext *context,
const std::string &expr)
{
if (this->IsDAG)
if (this->CheckResult == DAG)
{
return;
}
@ -91,16 +92,17 @@ void cmGeneratorExpressionDAGChecker::reportError(
}
//----------------------------------------------------------------------------
bool cmGeneratorExpressionDAGChecker::isDAG() const
cmGeneratorExpressionDAGChecker::Result
cmGeneratorExpressionDAGChecker::checkGraph() const
{
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
while (parent)
{
if (this->Target == parent->Target && this->Property == parent->Property)
{
return false;
return parent->Parent ? CYCLIC_REFERENCE : SELF_REFERENCE;
}
parent = parent->Parent;
}
return true;
return DAG;
}

View File

@ -25,12 +25,18 @@ struct cmGeneratorExpressionDAGChecker
const GeneratorExpressionContent *content,
cmGeneratorExpressionDAGChecker *parent);
bool check() const;
enum Result {
DAG,
SELF_REFERENCE,
CYCLIC_REFERENCE
};
Result check() const;
void reportError(cmGeneratorExpressionContext *context,
const std::string &expr);
private:
bool isDAG() const;
Result checkGraph() const;
private:
const cmGeneratorExpressionDAGChecker * const Parent;
@ -38,7 +44,7 @@ private:
const std::string Property;
const GeneratorExpressionContent * const Content;
const cmListFileBacktrace Backtrace;
bool IsDAG;
Result CheckResult;
};
#endif

View File

@ -381,10 +381,16 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
content,
dagCheckerParent);
if (!dagChecker.check())
switch (dagChecker.check())
{
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.reportError(context, content->GetOriginalExpression());
return std::string();
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
return std::string();
case cmGeneratorExpressionDAGChecker::DAG:
break;
}
const char *prop = target->GetProperty(propertyName.c_str());