summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-01-16 15:42:39 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-01-17 16:20:17 (GMT)
commit6c8d8afe344aa2e0ba0c5c881d397a28a559dcbd (patch)
tree4d1617d73ea6e2bb011da55b09f41d33bd6abbd9 /Source
parent1800f702a056b2eb25eb35daf9ed8d6474ecd0f9 (diff)
downloadCMake-6c8d8afe344aa2e0ba0c5c881d397a28a559dcbd.zip
CMake-6c8d8afe344aa2e0ba0c5c881d397a28a559dcbd.tar.gz
CMake-6c8d8afe344aa2e0ba0c5c881d397a28a559dcbd.tar.bz2
Add the $<TARGET_POLICY> expression
This new expression allows checking how a policy was set when a target was created. That information is only recorded for a subset of policies, so a whitelist is used.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmDocumentGeneratorExpressions.h4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx98
2 files changed, 102 insertions, 0 deletions
diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h
index fa21907..c2bf423 100644
--- a/Source/cmDocumentGeneratorExpressions.h
+++ b/Source/cmDocumentGeneratorExpressions.h
@@ -50,6 +50,10 @@
" $<TARGET_PROPERTY:tgt,prop> = The value of the property prop\n" \
"on the target tgt. Note that tgt is not added as a dependency of\n" \
"the target this expression is evaluated on.\n" \
+ " $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \
+ "the 'head' target was created, else '0'. If the policy was not " \
+ "set, the warning message for the policy will be emitted. This " \
+ "generator expression only works for a subset of policies.\n" \
"Boolean expressions:\n" \
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 8e40815a..2ddc058 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -488,6 +488,102 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
} targetNameNode;
//----------------------------------------------------------------------------
+static const char* targetPolicyWhitelist[] = {
+ "CMP0003"
+ , "CMP0004"
+ , "CMP0008"
+};
+
+cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
+{
+#define RETURN_POLICY(POLICY) \
+ if (strcmp(policy, #POLICY) == 0) \
+ { \
+ return tgt->GetPolicyStatus ## POLICY (); \
+ } \
+
+ RETURN_POLICY(CMP0003)
+ RETURN_POLICY(CMP0004)
+ RETURN_POLICY(CMP0008)
+
+#undef RETURN_POLICY
+
+ assert("!Unreachable code. Not a valid policy");
+ return cmPolicies::WARN;
+}
+
+cmPolicies::PolicyID policyForString(const char *policy_id)
+{
+#define RETURN_POLICY_ID(POLICY_ID) \
+ if (strcmp(policy_id, #POLICY_ID) == 0) \
+ { \
+ return cmPolicies:: POLICY_ID; \
+ } \
+
+ RETURN_POLICY_ID(CMP0003)
+ RETURN_POLICY_ID(CMP0004)
+ RETURN_POLICY_ID(CMP0008)
+
+#undef RETURN_POLICY_ID
+
+ assert("!Unreachable code. Not a valid policy");
+ return cmPolicies::CMP0002;
+}
+
+//----------------------------------------------------------------------------
+static const struct TargetPolicyNode : public cmGeneratorExpressionNode
+{
+ TargetPolicyNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context ,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_POLICY:prop> may only be used with targets. It may not "
+ "be used with add_custom_command.");
+ return std::string();
+ }
+ for (size_t i = 0;
+ i < (sizeof(targetPolicyWhitelist) /
+ sizeof(*targetPolicyWhitelist));
+ ++i)
+ {
+ const char *policy = targetPolicyWhitelist[i];
+ if (parameters.front() == policy)
+ {
+ cmMakefile *mf = context->HeadTarget->GetMakefile();
+ switch(statusForTarget(context->HeadTarget, policy))
+ {
+ case cmPolicies::WARN:
+ mf->IssueMessage(cmake::AUTHOR_WARNING,
+ mf->GetPolicies()->
+ GetPolicyWarning(policyForString(policy)));
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::OLD:
+ return "0";
+ case cmPolicies::NEW:
+ return "1";
+ }
+ }
+ }
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_POLICY:prop> may only be used with a limited number of "
+ "policies. Currently it may be used with policies CMP0003, CMP0004 "
+ "and CMP0008."
+ );
+ return std::string();
+ }
+
+} targetPolicyNode;
+
+//----------------------------------------------------------------------------
template<bool linker, bool soname>
struct TargetFilesystemArtifactResultCreator
{
@@ -714,6 +810,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &targetPropertyNode;
else if (identifier == "TARGET_NAME")
return &targetNameNode;
+ else if (identifier == "TARGET_POLICY")
+ return &targetPolicyNode;
else if (identifier == "BUILD_INTERFACE")
return &buildInterfaceNode;
else if (identifier == "INSTALL_INTERFACE")