summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--Source/cmDocumentGeneratorExpressions.h4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx98
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-NEW.cmake9
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-OLD.cmake21
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt0
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt1
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake14
-rw-r--r--Tests/RunCMake/CMP0004/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0004/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0004/empty.cpp0
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
16 files changed, 164 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")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt b/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt
new file mode 100644
index 0000000..a21cb6a
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt
@@ -0,0 +1,2 @@
+ Target "foo" links to item " bar " which has leading or trailing
+ whitespace. This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake b/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake
new file mode 100644
index 0000000..7c61961
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake
@@ -0,0 +1,9 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+
+target_link_libraries(foo "$<1: bar >")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt b/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt
new file mode 100644
index 0000000..782e45c
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt
@@ -0,0 +1,2 @@
+ Target "bat" links to item " bar " which has leading or trailing
+ whitespace. This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake b/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake
new file mode 100644
index 0000000..d6ed72c
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 OLD)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+add_library(bing SHARED empty.cpp)
+add_library(bung SHARED empty.cpp)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(bat SHARED empty.cpp)
+
+target_link_libraries(foo "$<1: bar >")
+target_link_libraries(bing "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
+target_link_libraries(bung "$<$<TARGET_POLICY:CMP0004>: bar >")
+
+# The line below causes the error because the policy is NEW when bat
+# is created.
+target_link_libraries(bat "$<1: bar >")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt
new file mode 100644
index 0000000..eed53e7
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt
@@ -0,0 +1,2 @@
+ Target "foo" links to item " bat " which has leading or trailing
+ whitespace. This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake b/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake
new file mode 100644
index 0000000..eab680a
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+add_library(bat SHARED empty.cpp)
+
+# The negation here avoids the error.
+target_link_libraries(foo "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
+
+# The below line causes the error.
+target_link_libraries(foo "$<$<TARGET_POLICY:CMP0004>: bat >")
diff --git a/Tests/RunCMake/CMP0004/CMakeLists.txt b/Tests/RunCMake/CMP0004/CMakeLists.txt
new file mode 100644
index 0000000..e8db6b0
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0004/RunCMakeTest.cmake b/Tests/RunCMake/CMP0004/RunCMakeTest.cmake
new file mode 100644
index 0000000..950d0ed
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0004-OLD)
+run_cmake(CMP0004-NEW)
+run_cmake(CMP0004-policy-genex)
diff --git a/Tests/RunCMake/CMP0004/empty.cpp b/Tests/RunCMake/CMP0004/empty.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/empty.cpp
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 9b133b2..8822200 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -59,6 +59,7 @@ add_RunCMake_test(find_package)
add_RunCMake_test(include)
add_RunCMake_test(include_directories)
add_RunCMake_test(list)
+add_RunCMake_test(CMP0004)
if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
add_RunCMake_test(include_external_msproject)