diff options
author | Stephen Kelly <steveire@gmail.com> | 2013-04-29 10:00:53 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2013-05-06 13:55:45 (GMT) |
commit | 26dba6a1622422d3742254aa2ecab97f9a58cb2b (patch) | |
tree | 6b83e62275e5f435d5ac915d9f1501df4b39535d | |
parent | b8259c3d69258b884383559b74d37486b6a06ca2 (diff) | |
download | CMake-26dba6a1622422d3742254aa2ecab97f9a58cb2b.zip CMake-26dba6a1622422d3742254aa2ecab97f9a58cb2b.tar.gz CMake-26dba6a1622422d3742254aa2ecab97f9a58cb2b.tar.bz2 |
Fix include dir propagation from conditionally linked targets
Generator expressions, including configuration-specific expressions may
be used as link libraries of targets. The old-style keywords of
target_link_libraries are handled in terms of new generator expressions.
However, the generator expressions expect target names to be valid
against a regular expression, whereas target_link_libraries does not
require validation. In generator expression constructed without any
action from the user we need to ensure that only valid expressions are
generated. Ensure that strings which are not valid target names are not
used in generator expressions which validate the argument.
Code like
target_link_libraries(B debug A)
generates usage requirement references such as "$<$<CONFIG:DEBUG>:A>".
When cmTarget::GetIncludeDirectories uses such references it generates
expressions like:
$<TARGET_PROPERTY:$<$<CONFIG:DEBUG>:A>,INTERFACE_INCLUDE_DIRECTORIES>
When the conditions are false such references evaluate as an empty
string and the expression fails with an error such as:
$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name.
Fix this by teaching cmTarget::GetIncludeDirectories to wrap the above
expression inside a conditional:
$<$<BOOL:$<$<CONFIG:DEBUG>:A>>:...>
so that $<TARGET_PROPERTY:...> will not be evaluated with an empty
target.
-rw-r--r-- | Source/cmTarget.cxx | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 186e203..1ccfa47 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2709,10 +2709,14 @@ void cmTarget::SetProperty(const char* prop, const char* value) if (strcmp(prop, "LINK_LIBRARIES") == 0) { this->Internal->LinkInterfaceIncludeDirectoriesEntries.clear(); - cmListFileBacktrace lfbt; - this->Makefile->GetBacktrace(lfbt); - cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + if (cmGeneratorExpression::IsValidTargetName(value) + || cmGeneratorExpression::Find(value) != std::string::npos) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + } // Fall through } this->Properties.SetProperty(prop, value, cmProperty::TARGET); @@ -2738,10 +2742,14 @@ void cmTarget::AppendProperty(const char* prop, const char* value, } if (strcmp(prop, "LINK_LIBRARIES") == 0) { - cmListFileBacktrace lfbt; - this->Makefile->GetBacktrace(lfbt); - cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + if (cmGeneratorExpression::IsValidTargetName(value) + || cmGeneratorExpression::Find(value) != std::string::npos) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + } // Fall through } this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); @@ -2950,16 +2958,23 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) ge.Parse(it->Value); std::string result = cge->Evaluate(this->Makefile, config, false, this, 0, 0); - if (!cmGeneratorExpression::IsValidTargetName(result.c_str()) - || !this->Makefile->FindTargetToUse(result.c_str())) + if (!this->Makefile->FindTargetToUse(result.c_str())) { continue; } } + std::string includeGenex = "$<TARGET_PROPERTY:" + + it->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 = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">"; + } cmGeneratorExpression ge(it->Backtrace); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( - "$<TARGET_PROPERTY:" + - it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); + includeGenex); this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back( new cmTargetInternals::IncludeDirectoriesEntry(cge, |