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),
|
: Parent(parent), Target(target), Property(property),
|
||||||
Content(content), Backtrace(backtrace)
|
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,
|
cmGeneratorExpressionContext *context,
|
||||||
const std::string &expr)
|
const std::string &expr)
|
||||||
{
|
{
|
||||||
if (this->IsDAG)
|
if (this->CheckResult == DAG)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -91,16 +92,17 @@ void cmGeneratorExpressionDAGChecker::reportError(
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmGeneratorExpressionDAGChecker::isDAG() const
|
cmGeneratorExpressionDAGChecker::Result
|
||||||
|
cmGeneratorExpressionDAGChecker::checkGraph() const
|
||||||
{
|
{
|
||||||
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||||
while (parent)
|
while (parent)
|
||||||
{
|
{
|
||||||
if (this->Target == parent->Target && this->Property == parent->Property)
|
if (this->Target == parent->Target && this->Property == parent->Property)
|
||||||
{
|
{
|
||||||
return false;
|
return parent->Parent ? CYCLIC_REFERENCE : SELF_REFERENCE;
|
||||||
}
|
}
|
||||||
parent = parent->Parent;
|
parent = parent->Parent;
|
||||||
}
|
}
|
||||||
return true;
|
return DAG;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,18 @@ struct cmGeneratorExpressionDAGChecker
|
||||||
const GeneratorExpressionContent *content,
|
const GeneratorExpressionContent *content,
|
||||||
cmGeneratorExpressionDAGChecker *parent);
|
cmGeneratorExpressionDAGChecker *parent);
|
||||||
|
|
||||||
bool check() const;
|
enum Result {
|
||||||
|
DAG,
|
||||||
|
SELF_REFERENCE,
|
||||||
|
CYCLIC_REFERENCE
|
||||||
|
};
|
||||||
|
|
||||||
|
Result check() const;
|
||||||
|
|
||||||
void reportError(cmGeneratorExpressionContext *context,
|
void reportError(cmGeneratorExpressionContext *context,
|
||||||
const std::string &expr);
|
const std::string &expr);
|
||||||
private:
|
private:
|
||||||
bool isDAG() const;
|
Result checkGraph() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const cmGeneratorExpressionDAGChecker * const Parent;
|
const cmGeneratorExpressionDAGChecker * const Parent;
|
||||||
|
@ -38,7 +44,7 @@ private:
|
||||||
const std::string Property;
|
const std::string Property;
|
||||||
const GeneratorExpressionContent * const Content;
|
const GeneratorExpressionContent * const Content;
|
||||||
const cmListFileBacktrace Backtrace;
|
const cmListFileBacktrace Backtrace;
|
||||||
bool IsDAG;
|
Result CheckResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -381,10 +381,16 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
content,
|
content,
|
||||||
dagCheckerParent);
|
dagCheckerParent);
|
||||||
|
|
||||||
if (!dagChecker.check())
|
switch (dagChecker.check())
|
||||||
{
|
{
|
||||||
|
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
|
||||||
dagChecker.reportError(context, content->GetOriginalExpression());
|
dagChecker.reportError(context, content->GetOriginalExpression());
|
||||||
return std::string();
|
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());
|
const char *prop = target->GetProperty(propertyName.c_str());
|
||||||
|
|
Loading…
Reference in New Issue