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:
parent
d0f950fdba
commit
c67b8124f7
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue