diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 3e03c099e..5b79e3531 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -139,7 +139,7 @@ cmGeneratorExpressionDAGChecker::checkGraph() const } //---------------------------------------------------------------------------- -bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() +bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt) { const cmGeneratorExpressionDAGChecker *top = this; const cmGeneratorExpressionDAGChecker *parent = this->Parent; @@ -150,6 +150,12 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() } const char *prop = top->Property.c_str(); + + if (tgt) + { + return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0; + } + return (strcmp(prop, "LINK_LIBRARIES") == 0 || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 85b13e50e..95d466ae3 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -47,7 +47,7 @@ struct cmGeneratorExpressionDAGChecker void reportError(cmGeneratorExpressionContext *context, const std::string &expr); - bool EvaluatingLinkLibraries(); + bool EvaluatingLinkLibraries(const char *tgt = 0); #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) \ bool METHOD () const; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index d95006e5a..037ef31d7 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -469,8 +469,15 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode std::string Evaluate(const std::vector ¶meters, cmGeneratorExpressionContext *context, const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const + cmGeneratorExpressionDAGChecker *dagChecker) const { + if (dagChecker && dagChecker->EvaluatingLinkLibraries()) + { + reportError(context, content->GetOriginalExpression(), + "$ expression can not be used while evaluating " + "link libraries"); + return std::string(); + } if (parameters.size() != 0 && parameters.size() != 1) { reportError(context, content->GetOriginalExpression(), @@ -483,6 +490,7 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode reportError(context, content->GetOriginalExpression(), "$ may only be used with targets. It may not " "be used with add_custom_command."); + return std::string(); } const char *lang = target->GetLinkerLanguage(context->Config); @@ -1146,7 +1154,7 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode std::string Evaluate(const std::vector ¶meters, cmGeneratorExpressionContext *context, const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const + cmGeneratorExpressionDAGChecker *dagChecker) const { // Lookup the referenced target. std::string name = *parameters.begin(); @@ -1171,6 +1179,13 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode "Target \"" + name + "\" is not an executable or library."); return std::string(); } + if (dagChecker && dagChecker->EvaluatingLinkLibraries(name.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Expressions which require the linker language may not " + "be used while evaluating link libraries"); + return std::string(); + } context->DependTargets.insert(target); context->AllTargets.insert(target); diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt new file mode 100644 index 000000000..8e0591d34 --- /dev/null +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: + Error evaluating generator expression: + + \$ + + \$ expression can not be used while evaluating link libraries diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake new file mode 100644 index 000000000..e0f8c5724 --- /dev/null +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake @@ -0,0 +1,4 @@ + +add_library(foo SHARED empty.cpp) +add_library(bar SHARED empty.cpp) +target_link_libraries(foo $<$,anything>:bar>) diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake index a99548f05..6517a8105 100644 --- a/Tests/RunCMake/Languages/RunCMakeTest.cmake +++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake @@ -1,3 +1,6 @@ include(RunCMake) run_cmake(NoLangSHARED) +run_cmake(LINK_LANGUAGE-genex) +run_cmake(link-libraries-TARGET_FILE-genex) +run_cmake(link-libraries-TARGET_FILE-genex-ok) diff --git a/Tests/RunCMake/Languages/empty.cpp b/Tests/RunCMake/Languages/empty.cpp new file mode 100644 index 000000000..7279c5e0b --- /dev/null +++ b/Tests/RunCMake/Languages/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty(void) +{ + return 0; +} diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok-result.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok.cmake b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok.cmake new file mode 100644 index 000000000..f0fd6e5aa --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok.cmake @@ -0,0 +1,6 @@ + +enable_language(CXX) + +add_library(foo SHARED empty.cpp) +add_library(bar SHARED empty.cpp) +target_link_libraries(foo $<$,anything>:bar>) diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-result.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt new file mode 100644 index 000000000..2d7a3c9d6 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt @@ -0,0 +1,7 @@ +CMake Error: + Error evaluating generator expression: + + \$ + + Expressions which require the linker language may not be used while + evaluating link libraries diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex.cmake b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex.cmake new file mode 100644 index 000000000..eca73e977 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex.cmake @@ -0,0 +1,4 @@ + +add_library(foo SHARED empty.cpp) +add_library(bar SHARED empty.cpp) +target_link_libraries(foo $<$,anything>:bar>)