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.
This commit is contained in:
parent
1800f702a0
commit
6c8d8afe34
|
@ -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" \
|
||||
|
|
|
@ -487,6 +487,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> ¶meters,
|
||||
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")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -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.
|
|
@ -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 >")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -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.
|
|
@ -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 >")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -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.
|
|
@ -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 >")
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,5 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(CMP0004-OLD)
|
||||
run_cmake(CMP0004-NEW)
|
||||
run_cmake(CMP0004-policy-genex)
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue