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" \
|
" $<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" \
|
"on the target tgt. Note that tgt is not added as a dependency of\n" \
|
||||||
"the target this expression is evaluated on.\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" \
|
"Boolean expressions:\n" \
|
||||||
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
|
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
|
||||||
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
|
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
|
||||||
|
|
|
@ -487,6 +487,102 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
|
||||||
|
|
||||||
} targetNameNode;
|
} 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>
|
template<bool linker, bool soname>
|
||||||
struct TargetFilesystemArtifactResultCreator
|
struct TargetFilesystemArtifactResultCreator
|
||||||
|
@ -714,6 +810,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
||||||
return &targetPropertyNode;
|
return &targetPropertyNode;
|
||||||
else if (identifier == "TARGET_NAME")
|
else if (identifier == "TARGET_NAME")
|
||||||
return &targetNameNode;
|
return &targetNameNode;
|
||||||
|
else if (identifier == "TARGET_POLICY")
|
||||||
|
return &targetPolicyNode;
|
||||||
else if (identifier == "BUILD_INTERFACE")
|
else if (identifier == "BUILD_INTERFACE")
|
||||||
return &buildInterfaceNode;
|
return &buildInterfaceNode;
|
||||||
else if (identifier == "INSTALL_INTERFACE")
|
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)
|
||||||
add_RunCMake_test(include_directories)
|
add_RunCMake_test(include_directories)
|
||||||
add_RunCMake_test(list)
|
add_RunCMake_test(list)
|
||||||
|
add_RunCMake_test(CMP0004)
|
||||||
|
|
||||||
if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
|
if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
|
||||||
add_RunCMake_test(include_external_msproject)
|
add_RunCMake_test(include_external_msproject)
|
||||||
|
|
Loading…
Reference in New Issue