diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index b8889ac205..fa21907177 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -37,6 +37,7 @@ "target in the same buildsystem. Expands to the empty string " \ "otherwise.\n" \ " $ = main file (.exe, .so.1.2, .a)\n" \ + " $ = '1' if tgt is a target, else '0'\n" \ " $ = file used to link (.a, .lib, .so)\n" \ " $ = file with soname (.so.3)\n" \ "where \"tgt\" is the name of a target. " \ diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index f4e4131230..8e40815af7 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -289,6 +289,22 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode } configurationTestNode; +static const struct TargetDefinedNode : public cmGeneratorExpressionNode +{ + TargetDefinedNode() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return context->Makefile->FindTargetToUse(parameters.front().c_str()) + ? "1" : "0"; + } +} targetDefinedNode; + //---------------------------------------------------------------------------- static const char* targetPropertyTransitiveWhitelist[] = { "INTERFACE_INCLUDE_DIRECTORIES" @@ -702,6 +718,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &buildInterfaceNode; else if (identifier == "INSTALL_INTERFACE") return &installInterfaceNode; + else if (identifier == "TARGET_DEFINED") + return &targetDefinedNode; return 0; } diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt index 84a23efc3a..a37c59708a 100644 --- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt @@ -23,4 +23,6 @@ add_executable(consumer target_compile_definitions(consumer PRIVATE target_compile_definitions importedlib + $<$:SHOULD_NOT_BE_DEFINED> + $<$:SHOULD_BE_DEFINED> ) diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp index e3788ddb22..1ef657d5ae 100644 --- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp +++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp @@ -15,4 +15,12 @@ #error Expected MY_IMPORTEDINTERFACE_DEFINE #endif +#ifdef SHOULD_NOT_BE_DEFINED +#error Unexpected SHOULD_NOT_BE_DEFINED +#endif + +#ifndef SHOULD_BE_DEFINED +#error Expected SHOULD_BE_DEFINED +#endif + int main() { return 0; }