genex: Add TARGET_EXISTS to check for target existence

Define `$<TARGET_EXISTS:a>` to `1` if `a` is an existed target name,
else `0`.
This commit is contained in:
Alex Turbov
2018-03-07 12:01:28 +08:00
committed by Brad King
parent 674c5b3066
commit 7fec336bf7
14 changed files with 83 additions and 0 deletions

View File

@@ -59,6 +59,8 @@ Available logical expressions are:
``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0``
``$<IN_LIST:a,b>``
``1`` if ``a`` is IN_LIST ``b``, else ``0``
``$<TARGET_EXISTS:tgt>``
``1`` if ``tgt`` is an existed target name, else ``0``.
``$<CONFIG:cfg>``
``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by

View File

@@ -0,0 +1,6 @@
genex-TARGET_EXISTS
-------------------
* A new ``$<TARGET_EXISTS:...>``
:manual:`generator expression <cmake-generator-expressions(7)>`
has been added.

View File

@@ -300,6 +300,37 @@ static const struct InListNode : public cmGeneratorExpressionNode
}
} inListNode;
static const struct TargetExistsNode : public cmGeneratorExpressionNode
{
TargetExistsNode() {}
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
const std::vector<std::string>& parameters,
cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.size() != 1) {
reportError(context, content->GetOriginalExpression(),
"$<TARGET_EXISTS:...> expression requires one parameter");
return std::string();
}
std::string targetName = parameters.front();
if (targetName.empty() ||
!cmGeneratorExpression::IsValidTargetName(targetName)) {
reportError(context, content->GetOriginalExpression(),
"$<TARGET_EXISTS:tgt> expression requires a non-empty "
"valid target name.");
return std::string();
}
return context->LG->GetMakefile()->FindTargetToUse(targetName) ? "1" : "0";
}
} targetExistsNode;
static const struct LowerCaseNode : public cmGeneratorExpressionNode
{
LowerCaseNode() {}
@@ -1865,6 +1896,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["TARGET_NAME"] = &targetNameNode;
nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
nodeMap["TARGET_POLICY"] = &targetPolicyNode;
nodeMap["TARGET_EXISTS"] = &targetExistsNode;
nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
nodeMap["INSTALL_PREFIX"] = &installPrefixNode;

View File

@@ -34,6 +34,10 @@ run_cmake(OUTPUT_NAME-recursion)
run_cmake(TARGET_PROPERTY-LOCATION)
run_cmake(TARGET_PROPERTY-SOURCES)
run_cmake(LINK_ONLY-not-linking)
run_cmake(TARGET_EXISTS-no-arg)
run_cmake(TARGET_EXISTS-empty-arg)
run_cmake(TARGET_EXISTS)
run_cmake(TARGET_EXISTS-not-a-target)
run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)

View File

@@ -0,0 +1,6 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_EXISTS-generated.txt" content)
set(expected "1")
if(NOT content STREQUAL expected)
set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
endif()

View File

@@ -0,0 +1,8 @@
CMake Error at TARGET_EXISTS-empty-arg.cmake:2 \(file\):
Error evaluating generator expression:
\$<TARGET_EXISTS:>
\$<TARGET_EXISTS:tgt> expression requires a non-empty valid target name.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
cmake_policy(SET CMP0070 NEW)
file(GENERATE OUTPUT TARGET_EXISTS-generated.txt CONTENT "$<TARGET_EXISTS:${empty}>")

View File

@@ -0,0 +1,8 @@
CMake Error at TARGET_EXISTS-no-arg.cmake:2 \(file\):
Error evaluating generator expression:
\$<TARGET_EXISTS>
\$<TARGET_EXISTS> expression requires exactly one parameter.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
cmake_policy(SET CMP0070 NEW)
file(GENERATE OUTPUT TARGET_EXISTS-generated.txt CONTENT "$<TARGET_EXISTS>")

View File

@@ -0,0 +1,6 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_EXISTS-not-a-target-generated.txt" content)
set(expected "0")
if(NOT content STREQUAL expected)
set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
endif()

View File

@@ -0,0 +1,2 @@
cmake_policy(SET CMP0070 NEW)
file(GENERATE OUTPUT TARGET_EXISTS-not-a-target-generated.txt CONTENT "$<TARGET_EXISTS:just-random-string>")

View File

@@ -0,0 +1,3 @@
cmake_policy(SET CMP0070 NEW)
add_custom_target(foo)
file(GENERATE OUTPUT TARGET_EXISTS-generated.txt CONTENT "$<TARGET_EXISTS:foo>")