From 7fec336bf72684d5b2610e7d6d6041f40c61e833 Mon Sep 17 00:00:00 2001 From: Alex Turbov Date: Wed, 7 Mar 2018 12:01:28 +0800 Subject: genex: Add TARGET_EXISTS to check for target existence Define `$` to `1` if `a` is an existed target name, else `0`. --- Help/manual/cmake-generator-expressions.7.rst | 2 ++ Help/release/dev/genex-TARGET_EXISTS.rst | 6 ++++ Source/cmGeneratorExpressionNode.cxx | 32 ++++++++++++++++++++++ .../GeneratorExpression/RunCMakeTest.cmake | 4 +++ .../GeneratorExpression/TARGET_EXISTS-check.cmake | 6 ++++ .../TARGET_EXISTS-empty-arg-result.txt | 1 + .../TARGET_EXISTS-empty-arg-stderr.txt | 8 ++++++ .../TARGET_EXISTS-empty-arg.cmake | 2 ++ .../TARGET_EXISTS-no-arg-result.txt | 1 + .../TARGET_EXISTS-no-arg-stderr.txt | 8 ++++++ .../GeneratorExpression/TARGET_EXISTS-no-arg.cmake | 2 ++ .../TARGET_EXISTS-not-a-target-check.cmake | 6 ++++ .../TARGET_EXISTS-not-a-target.cmake | 2 ++ .../GeneratorExpression/TARGET_EXISTS.cmake | 3 ++ 14 files changed, 83 insertions(+) create mode 100644 Help/release/dev/genex-TARGET_EXISTS.rst create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-check.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-result.txt create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-result.txt create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target-check.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_EXISTS.cmake diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 04cb1dc..d3514ab 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -59,6 +59,8 @@ Available logical expressions are: ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0`` ``$`` ``1`` if ``a`` is IN_LIST ``b``, else ``0`` +``$`` + ``1`` if ``tgt`` is an existed target name, else ``0``. ``$`` ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison. The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_` is also considered by diff --git a/Help/release/dev/genex-TARGET_EXISTS.rst b/Help/release/dev/genex-TARGET_EXISTS.rst new file mode 100644 index 0000000..f305522 --- /dev/null +++ b/Help/release/dev/genex-TARGET_EXISTS.rst @@ -0,0 +1,6 @@ +genex-TARGET_EXISTS +------------------- + +* A new ``$`` + :manual:`generator expression ` + has been added. diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 0d22028..f444113 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -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& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override + { + if (parameters.size() != 1) { + reportError(context, content->GetOriginalExpression(), + "$ expression requires one parameter"); + return std::string(); + } + + std::string targetName = parameters.front(); + if (targetName.empty() || + !cmGeneratorExpression::IsValidTargetName(targetName)) { + reportError(context, content->GetOriginalExpression(), + "$ 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; diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 2486259..f9a5cae 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-check.cmake new file mode 100644 index 0000000..c4c3a51 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-check.cmake @@ -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() diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-stderr.txt new file mode 100644 index 0000000..1df6e28 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at TARGET_EXISTS-empty-arg.cmake:2 \(file\): + Error evaluating generator expression: + + \$ + + \$ expression requires a non-empty valid target name. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg.cmake new file mode 100644 index 0000000..e387abc --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-empty-arg.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT TARGET_EXISTS-generated.txt CONTENT "$") diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-stderr.txt new file mode 100644 index 0000000..69e6130 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at TARGET_EXISTS-no-arg.cmake:2 \(file\): + Error evaluating generator expression: + + \$ + + \$ expression requires exactly one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg.cmake new file mode 100644 index 0000000..0a5ce32 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-no-arg.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT TARGET_EXISTS-generated.txt CONTENT "$") diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target-check.cmake new file mode 100644 index 0000000..35ba267 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target-check.cmake @@ -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() diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target.cmake new file mode 100644 index 0000000..d8a8d3e --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS-not-a-target.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT TARGET_EXISTS-not-a-target-generated.txt CONTENT "$") diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS.cmake new file mode 100644 index 0000000..9a83b34 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_EXISTS.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0070 NEW) +add_custom_target(foo) +file(GENERATE OUTPUT TARGET_EXISTS-generated.txt CONTENT "$") -- cgit v0.12