|
|
@@ -238,6 +238,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
|
|
|
const GeneratorExpressionContent *,
|
|
|
cmGeneratorExpressionDAGChecker *) const
|
|
|
{
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
return context->Config ? context->Config : "";
|
|
|
}
|
|
|
} configurationNode;
|
|
|
@@ -262,6 +263,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
|
|
"Expression syntax not recognized.");
|
|
|
return std::string();
|
|
|
}
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
if (!context->Config)
|
|
|
{
|
|
|
return parameters.front().empty() ? "1" : "0";
|
|
|
@@ -435,6 +437,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|
|
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
|
|
|
// No error. We just skip cyclic references.
|
|
|
return std::string();
|
|
|
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
|
|
|
+ // No error. We're not going to find anything new here.
|
|
|
+ return std::string();
|
|
|
case cmGeneratorExpressionDAGChecker::DAG:
|
|
|
break;
|
|
|
}
|
|
|
@@ -452,12 +457,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|
|
}
|
|
|
if (propertyName == "POSITION_INDEPENDENT_CODE")
|
|
|
{
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
return target->GetLinkInterfaceDependentBoolProperty(
|
|
|
"POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
|
|
|
}
|
|
|
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
|
|
|
context->Config))
|
|
|
{
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
return target->GetLinkInterfaceDependentBoolProperty(
|
|
|
propertyName,
|
|
|
context->Config) ? "1" : "0";
|
|
|
@@ -465,9 +472,12 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|
|
if (target->IsLinkInterfaceDependentStringProperty(propertyName,
|
|
|
context->Config))
|
|
|
{
|
|
|
- return target->GetLinkInterfaceDependentStringProperty(
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
+ const char *propContent =
|
|
|
+ target->GetLinkInterfaceDependentStringProperty(
|
|
|
propertyName,
|
|
|
context->Config);
|
|
|
+ return propContent ? propContent : "";
|
|
|
}
|
|
|
|
|
|
return std::string();
|
|
|
@@ -481,12 +491,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|
|
if (targetPropertyTransitiveWhitelist[i] == propertyName)
|
|
|
{
|
|
|
cmGeneratorExpression ge(context->Backtrace);
|
|
|
- return ge.Parse(prop)->Evaluate(context->Makefile,
|
|
|
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
|
|
|
+ std::string result = cge->Evaluate(context->Makefile,
|
|
|
context->Config,
|
|
|
context->Quiet,
|
|
|
context->HeadTarget,
|
|
|
target,
|
|
|
&dagChecker);
|
|
|
+
|
|
|
+ if (cge->GetHadContextSensitiveCondition())
|
|
|
+ {
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
}
|
|
|
}
|
|
|
return prop;
|
|
|
@@ -580,6 +597,9 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
|
|
|
"be used with add_custom_command.");
|
|
|
return std::string();
|
|
|
}
|
|
|
+
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
+
|
|
|
for (size_t i = 0;
|
|
|
i < (sizeof(targetPolicyWhitelist) /
|
|
|
sizeof(*targetPolicyWhitelist));
|
|
|
@@ -619,19 +639,114 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
|
|
|
{
|
|
|
InstallPrefixNode() {}
|
|
|
|
|
|
- virtual bool GeneratesContent() const { return false; }
|
|
|
+ virtual bool GeneratesContent() const { return true; }
|
|
|
virtual int NumExpectedParameters() const { return 0; }
|
|
|
|
|
|
std::string Evaluate(const std::vector<std::string> &,
|
|
|
- cmGeneratorExpressionContext *,
|
|
|
- const GeneratorExpressionContent *,
|
|
|
+ cmGeneratorExpressionContext *context,
|
|
|
+ const GeneratorExpressionContent *content,
|
|
|
cmGeneratorExpressionDAGChecker *) const
|
|
|
{
|
|
|
+ reportError(context, content->GetOriginalExpression(),
|
|
|
+ "INSTALL_PREFIX is a marker for install(EXPORT) only. It "
|
|
|
+ "should never be evaluated.");
|
|
|
return std::string();
|
|
|
}
|
|
|
|
|
|
} installPrefixNode;
|
|
|
|
|
|
+//----------------------------------------------------------------------------
|
|
|
+static const struct LinkedNode : public cmGeneratorExpressionNode
|
|
|
+{
|
|
|
+ LinkedNode() {}
|
|
|
+
|
|
|
+ virtual bool GeneratesContent() const { return true; }
|
|
|
+ virtual int NumExpectedParameters() const { return 1; }
|
|
|
+ virtual bool RequiresLiteralInput() const { return true; }
|
|
|
+
|
|
|
+ std::string Evaluate(const std::vector<std::string> ¶meters,
|
|
|
+ cmGeneratorExpressionContext *context,
|
|
|
+ const GeneratorExpressionContent *content,
|
|
|
+ cmGeneratorExpressionDAGChecker *dagChecker) const
|
|
|
+ {
|
|
|
+ if (dagChecker->EvaluatingIncludeDirectories())
|
|
|
+ {
|
|
|
+ return this->GetInterfaceProperty(parameters.front(),
|
|
|
+ "INCLUDE_DIRECTORIES",
|
|
|
+ context, content, dagChecker);
|
|
|
+ }
|
|
|
+ if (dagChecker->EvaluatingCompileDefinitions())
|
|
|
+ {
|
|
|
+ return this->GetInterfaceProperty(parameters.front(),
|
|
|
+ "COMPILE_DEFINITIONS",
|
|
|
+ context, content, dagChecker);
|
|
|
+ }
|
|
|
+
|
|
|
+ reportError(context, content->GetOriginalExpression(),
|
|
|
+ "$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and "
|
|
|
+ "COMPILE_DEFINITIONS properties.");
|
|
|
+
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+
|
|
|
+private:
|
|
|
+ std::string GetInterfaceProperty(const std::string &item,
|
|
|
+ const std::string &prop,
|
|
|
+ cmGeneratorExpressionContext *context,
|
|
|
+ const GeneratorExpressionContent *content,
|
|
|
+ cmGeneratorExpressionDAGChecker *dagCheckerParent) const
|
|
|
+ {
|
|
|
+ cmTarget *target = context->CurrentTarget
|
|
|
+ ->GetMakefile()->FindTargetToUse(item.c_str());
|
|
|
+ if (!target)
|
|
|
+ {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+ std::string propertyName = "INTERFACE_" + prop;
|
|
|
+ const char *propContent = target->GetProperty(propertyName.c_str());
|
|
|
+ if (!propContent)
|
|
|
+ {
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+
|
|
|
+ cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
|
|
|
+ target->GetName(),
|
|
|
+ propertyName,
|
|
|
+ content,
|
|
|
+ dagCheckerParent);
|
|
|
+
|
|
|
+ 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::ALREADY_SEEN:
|
|
|
+ // No error. We're not going to find anything new here.
|
|
|
+ return std::string();
|
|
|
+ case cmGeneratorExpressionDAGChecker::DAG:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ cmGeneratorExpression ge(context->Backtrace);
|
|
|
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent);
|
|
|
+ std::string result = cge->Evaluate(context->Makefile,
|
|
|
+ context->Config,
|
|
|
+ context->Quiet,
|
|
|
+ context->HeadTarget,
|
|
|
+ target,
|
|
|
+ &dagChecker);
|
|
|
+ if (cge->GetHadContextSensitiveCondition())
|
|
|
+ {
|
|
|
+ context->HadContextSensitiveCondition = true;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+} linkedNode;
|
|
|
+
|
|
|
//----------------------------------------------------------------------------
|
|
|
template<bool linker, bool soname>
|
|
|
struct TargetFilesystemArtifactResultCreator
|
|
|
@@ -869,6 +984,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|
|
return &targetDefinedNode;
|
|
|
else if (identifier == "INSTALL_PREFIX")
|
|
|
return &installPrefixNode;
|
|
|
+ else if (identifier == "LINKED")
|
|
|
+ return &linkedNode;
|
|
|
return 0;
|
|
|
|
|
|
}
|