diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 6170e92e9..c13da50da 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -553,15 +553,16 @@ void cmComputeLinkDepends::AddDirectLinkEntries() } //---------------------------------------------------------------------------- +template void cmComputeLinkDepends::AddLinkEntries( - int depender_index, std::vector const& libs) + int depender_index, std::vector const& libs) { // Track inferred dependency sets implied by this list. std::map dependSets; // Loop over the libraries linked directly by the depender. - for(std::vector::const_iterator li = libs.begin(); + for(typename std::vector::const_iterator li = libs.begin(); li != libs.end(); ++li) { // Skip entries that will resolve to the target getting linked or diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 3207ecbf5..a931726d9 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -80,8 +80,8 @@ private: int AddLinkEntry(cmLinkItem const& item); void AddVarLinkEntries(int depender_index, const char* value); void AddDirectLinkEntries(); - void AddLinkEntries(int depender_index, - std::vector const& libs); + template + void AddLinkEntries(int depender_index, std::vector const& libs); cmTarget const* FindTargetToLink(int depender_index, const std::string& name); diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 3929af40d..75d3967bc 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -255,7 +255,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // A target should not depend on itself. emitted.insert(depender->GetName()); - for(std::vector::const_iterator + for(std::vector::const_iterator lib = impl->Libraries.begin(); lib != impl->Libraries.end(); ++lib) { diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index b648eb2d8..13eac3bd3 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -799,13 +799,14 @@ static const char* targetPropertyTransitiveWhitelist[] = { #undef TRANSITIVE_PROPERTY_NAME -std::string getLinkedTargetsContent( - std::vector &targets, - cmTarget const* target, - cmTarget const* headTarget, - cmGeneratorExpressionContext *context, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string &interfacePropertyName) +std::string +getLinkedTargetsContent( + std::vector &targets, + cmTarget const* target, + cmTarget const* headTarget, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) { cmGeneratorExpression ge(&context->Backtrace); @@ -841,15 +842,17 @@ std::string getLinkedTargetsContent( return linkedTargetsContent; } -std::string getLinkedTargetsContent(std::vector const &libraries, - cmTarget const* target, - cmTarget const* headTarget, - cmGeneratorExpressionContext *context, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string &interfacePropertyName) +std::string +getLinkedTargetsContent( + std::vector const &libraries, + cmTarget const* target, + cmTarget const* headTarget, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) { std::vector tgts; - for (std::vector::const_iterator + for (std::vector::const_iterator it = libraries.begin(); it != libraries.end(); ++it) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index fd82d1742..eccb06ada 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -475,8 +475,8 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir, } std::set uniqueDeps; - for(std::vector::const_iterator li = impl->Libraries.begin(); - li != impl->Libraries.end(); ++li) + for(std::vector::const_iterator + li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { cmTarget const* tgt = li->Target; if (!tgt) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d27293a4d..0a7724cb8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -165,14 +165,16 @@ public: std::set UtilityItems; bool UtilityItemsDone; - struct TargetPropertyEntry { + class TargetPropertyEntry { + static cmLinkImplItem NoLinkImplItem; + public: TargetPropertyEntry(cmsys::auto_ptr cge, - const std::string &targetName = std::string()) - : ge(cge), TargetName(targetName) + cmLinkImplItem const& item = NoLinkImplItem) + : ge(cge), LinkImplItem(item) {} const cmsys::auto_ptr ge; std::vector CachedEntries; - const std::string TargetName; + cmLinkImplItem const& LinkImplItem; }; std::vector IncludeDirectoriesEntries; std::vector CompileOptionsEntries; @@ -181,6 +183,10 @@ public: std::vector SourceEntries; std::vector LinkImplementationPropertyEntries; + void AddInterfaceEntries( + cmTarget const* thisTarget, std::string const& config, + std::string const& prop, std::vector& entries); + std::map > CachedLinkInterfaceIncludeDirectoriesEntries; std::map > @@ -202,6 +208,8 @@ public: std::map CacheLinkImplementationClosureDone; }; +cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; + //---------------------------------------------------------------------------- void deleteAndClear( std::vector &entries) @@ -770,45 +778,9 @@ void cmTarget::GetSourceFiles(std::vector &files, if (!this->Internal->CacheLinkInterfaceSourcesDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, &dagChecker); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string sourceGenex = "$Value + ",INTERFACE_SOURCES>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - sourceGenex = "$<$Value + ">:" + sourceGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - sourceGenex); - - this->Internal - ->CachedLinkInterfaceSourcesEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_SOURCES", + this->Internal->CachedLinkInterfaceSourcesEntries[config]); } std::vector::size_type numFilesBefore = files.size(); @@ -2044,6 +2016,10 @@ static void processIncludeDirectories(cmTarget const* tgt, for (std::vector::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { + cmLinkImplItem const& item = (*it)->LinkImplItem; + std::string const& targetName = item; + bool const fromImported = item.Target && item.Target->IsImported(); + bool const checkCMP0027 = item.FromGenex; bool testIsOff = true; bool cacheIncludes = false; std::vector& entryIncludes = (*it)->CachedEntries; @@ -2069,36 +2045,12 @@ static void processIncludeDirectories(cmTarget const* tgt, for(std::vector::iterator li = entryIncludes.begin(); li != entryIncludes.end(); ++li) { - std::string targetName = (*it)->TargetName; - std::string evaluatedTargetName; - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(targetName); - evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0); - } - - cmTarget *dependentTarget = mf->FindTargetToUse(targetName); - - const bool fromImported = dependentTarget - && dependentTarget->IsImported(); - - cmTarget *evaluatedDependentTarget = - (targetName != evaluatedTargetName) - ? mf->FindTargetToUse(evaluatedTargetName) - : 0; - - targetName = evaluatedTargetName; - - const bool fromEvaluatedImported = evaluatedDependentTarget - && evaluatedDependentTarget->IsImported(); - - if ((fromImported || fromEvaluatedImported) + if (fromImported && !cmSystemTools::FileExists(li->c_str())) { cmOStringStream e; cmake::MessageType messageType = cmake::FATAL_ERROR; - if (fromEvaluatedImported) + if (checkCMP0027) { switch(tgt->GetPolicyStatusCMP0027()) { @@ -2238,50 +2190,14 @@ cmTarget::GetIncludeDirectories(const std::string& config) const if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string result = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(result)) - { - continue; - } - } - std::string includeGenex = "$Value + ",INTERFACE_INCLUDE_DIRECTORIES>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - includeGenex = "$<$Value + ">:" + includeGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - includeGenex); - - this->Internal - ->CachedLinkInterfaceIncludeDirectoriesEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_INCLUDE_DIRECTORIES", + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[config]); if(this->Makefile->IsOn("APPLE")) { LinkImplementation const* impl = this->GetLinkImplementation(config); - for(std::vector::const_iterator + for(std::vector::const_iterator it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { @@ -2462,45 +2378,9 @@ void cmTarget::GetCompileOptions(std::vector &result, if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string optionGenex = "$Value + ",INTERFACE_COMPILE_OPTIONS>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - optionGenex = "$<$Value + ">:" + optionGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - optionGenex); - - this->Internal - ->CachedLinkInterfaceCompileOptionsEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_OPTIONS", + this->Internal->CachedLinkInterfaceCompileOptionsEntries[config]); } processCompileOptions(this, @@ -2572,45 +2452,9 @@ void cmTarget::GetCompileDefinitions(std::vector &list, if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string defsGenex = "$Value + ",INTERFACE_COMPILE_DEFINITIONS>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - defsGenex = "$<$Value + ">:" + defsGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - defsGenex); - - this->Internal - ->CachedLinkInterfaceCompileDefinitionsEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_DEFINITIONS", + this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[config]); if (!config.empty()) { std::string configPropName = "COMPILE_DEFINITIONS_" @@ -2719,45 +2563,9 @@ void cmTarget::GetCompileFeatures(std::vector &result, if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string featureGenex = "$Value + ",INTERFACE_COMPILE_FEATURES>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - featureGenex = "$<$Value + ">:" + featureGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - featureGenex); - - this->Internal - ->CachedLinkInterfaceCompileFeaturesEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_FEATURES", + this->Internal->CachedLinkInterfaceCompileFeaturesEntries[config]); } processCompileFeatures(this, @@ -3675,7 +3483,8 @@ void cmTarget::ComputeLinkClosure(const std::string& config, // Add interface languages from linked targets. cmTargetCollectLinkLanguages cll(this, config, languages, this); - for(std::vector::const_iterator li = impl->Libraries.begin(); + for(std::vector::const_iterator + li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { cll.Visit(*li); @@ -6242,7 +6051,8 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const cmTarget::LinkImplementation const* impl = this->GetLinkImplementationLibraries(config); - for(std::vector::const_iterator it = impl->Libraries.begin(); + for(std::vector::const_iterator + it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { processILibs(config, this, *it, tgts , emitted); @@ -6383,7 +6193,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, // The link implementation is the default link interface. LinkImplementation const* impl = this->GetLinkImplementationLibrariesInternal(config, headTarget); - iface.Libraries = impl->Libraries; + std::copy(impl->Libraries.begin(), impl->Libraries.end(), + std::back_inserter(iface.Libraries)); if(this->PolicyStatusCMP0022 == cmPolicies::WARN && !this->Internal->PolicyWarnedCMP0022 && !usage_requirements_only) { @@ -6397,12 +6208,12 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, headTarget, usage_requirements_only, ifaceLibs); } - if (ifaceLibs != impl->Libraries) + if (ifaceLibs != iface.Libraries) { std::string oldLibraries; std::string newLibraries; const char *sep = ""; - for(std::vector::const_iterator it + for(std::vector::const_iterator it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { oldLibraries += sep; @@ -6470,7 +6281,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, { cmTarget::LinkImplementation const* impl = thisTarget->GetLinkImplementation(config); - for(std::vector::const_iterator + for(std::vector::const_iterator li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { if(emitted.insert(*li).second) @@ -6546,6 +6357,31 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, iface.Complete = true; } +//---------------------------------------------------------------------------- +void cmTargetInternals::AddInterfaceEntries( + cmTarget const* thisTarget, std::string const& config, + std::string const& prop, std::vector& entries) +{ + if(cmTarget::LinkImplementation const* impl = + thisTarget->GetLinkImplementationLibraries(config)) + { + for (std::vector::const_iterator + it = impl->Libraries.begin(), end = impl->Libraries.end(); + it != end; ++it) + { + if(it->Target) + { + std::string genex = + "$"; + cmGeneratorExpression ge(&it->Backtrace); + cmsys::auto_ptr cge = ge.Parse(genex); + entries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge, *it)); + } + } + } +} + //---------------------------------------------------------------------------- cmTarget::LinkImplementation const* cmTarget::GetLinkImplementation(const std::string& config) const @@ -6621,12 +6457,9 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, cmGeneratorExpression ge(&le->Backtrace); cmsys::auto_ptr const cge = ge.Parse(le->Value); - cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, - config, - false, - head, - &dagChecker), - llibs); + std::string const evaluated = + cge->Evaluate(this->Makefile, config, false, head, &dagChecker); + cmSystemTools::ExpandListArgument(evaluated, llibs); for(std::vector::const_iterator li = llibs.begin(); li != llibs.end(); ++li) @@ -6674,7 +6507,8 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, // The entry is meant for this configuration. impl.Libraries.push_back( - cmLinkItem(name, this->FindTargetToLink(name))); + cmLinkImplItem(name, this->FindTargetToLink(name), + le->Backtrace, evaluated != le->Value)); } std::set const& seenProps = cge->GetSeenTargetProperties(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 9d1f96614..dc67f1e78 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -54,6 +54,20 @@ public: cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {} cmTarget const* Target; }; +class cmLinkImplItem: public cmLinkItem +{ +public: + cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {} + cmLinkImplItem(std::string const& n, + cmTarget const* t, + cmListFileBacktrace const& bt, + bool fromGenex): + cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {} + cmLinkImplItem(cmLinkImplItem const& r): + cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {} + cmListFileBacktrace Backtrace; + bool FromGenex; +}; struct cmTargetLinkInformationMap: public std::map @@ -296,7 +310,7 @@ public: std::vector Languages; // Libraries linked directly in this configuration. - std::vector Libraries; + std::vector Libraries; // Libraries linked directly in other configurations. // Needed only for OLD behavior of CMP0003. diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt index 82a34d530..17b8a5cfe 100644 --- a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt +++ b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt @@ -1,10 +1,3 @@ -CMake Debug Log: - Boolean compatibility of property "BOOL_PROP7" for target - "CompatibleInterface" \(result: "FALSE"\): - - \* Target "CompatibleInterface" property is implied by use. - \* Target "iface1" property value "FALSE" \(Agree\) -+ CMake Debug Log: Boolean compatibility of property "BOOL_PROP1" for target "CompatibleInterface" \(result: "TRUE"\): @@ -46,6 +39,13 @@ CMake Debug Log: \* Target "iface1" property value "FALSE" \(Interface set\) \* Target "iface2" property value "FALSE" \(Agree\) + +CMake Debug Log: + Boolean compatibility of property "BOOL_PROP7" for target + "CompatibleInterface" \(result: "FALSE"\): + + \* Target "CompatibleInterface" property is implied by use. + \* Target "iface1" property value "FALSE" \(Agree\) ++ CMake Debug Log: String compatibility of property "STRING_PROP1" for target "CompatibleInterface" \(result: "prop1"\): diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt index a5d5d5088..3a7f4806c 100644 --- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt @@ -1,7 +1,9 @@ -CMake Error: +CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\): Error evaluating generator expression: \$ LINKER_LANGUAGE target property can not be used while evaluating link - libraries + libraries for a static library +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt index 2d7a3c9d6..d8bc2387b 100644 --- a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt @@ -1,7 +1,9 @@ -CMake Error: +CMake Error at link-libraries-TARGET_FILE-genex.cmake:[0-9]+ \(target_link_libraries\): Error evaluating generator expression: \$ Expressions which require the linker language may not be used while evaluating link libraries +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)