Merge topic 'refactor-usage-requirement-evaluation'

93790506 cmTarget: Simplify INTERFACE_INCLUDE_DIRECTORIES usage requirement lookup
b5b098eb cmTarget: Simplify CMP0027 logic in processIncludeDirectories
5e07dcf7 cmTarget: Add to LinkImplementation whether each library was a genex
f77b384c cmTarget: Simplify INTERFACE_COMPILE_FEATURES usage requirement lookup
61ef8daa cmTarget: Simplify INTERFACE_COMPILE_DEFINITIONS usage requirement lookup
d9586f83 cmTarget: Simplify INTERFACE_COMPILE_OPTIONS usage requirement lookup
3156275b cmTarget: Simplify INTERFACE_SOURCES usage requirement lookup
363cd33e cmTarget: Add method to add usage requirements from linked interfaces
251e835b cmTarget: Add to LinkImplementation a backtrace for each library
848c8ccf cmTarget: Refactor LinkImplementation to allow more information
f85ccf23 cmGeneratorExpressionEvaluator: Shorten some long lines
82e91e34 cmComputeLinkDepends: Convert AddLinkEntries to a template
This commit is contained in:
Brad King 2014-07-07 08:54:40 -04:00 committed by CMake Topic Stage
commit 61be345115
10 changed files with 127 additions and 271 deletions

View File

@ -553,15 +553,16 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
template <typename T>
void void
cmComputeLinkDepends::AddLinkEntries( cmComputeLinkDepends::AddLinkEntries(
int depender_index, std::vector<cmLinkItem> const& libs) int depender_index, std::vector<T> const& libs)
{ {
// Track inferred dependency sets implied by this list. // Track inferred dependency sets implied by this list.
std::map<int, DependSet> dependSets; std::map<int, DependSet> dependSets;
// Loop over the libraries linked directly by the depender. // Loop over the libraries linked directly by the depender.
for(std::vector<cmLinkItem>::const_iterator li = libs.begin(); for(typename std::vector<T>::const_iterator li = libs.begin();
li != libs.end(); ++li) li != libs.end(); ++li)
{ {
// Skip entries that will resolve to the target getting linked or // Skip entries that will resolve to the target getting linked or

View File

@ -80,8 +80,8 @@ private:
int AddLinkEntry(cmLinkItem const& item); int AddLinkEntry(cmLinkItem const& item);
void AddVarLinkEntries(int depender_index, const char* value); void AddVarLinkEntries(int depender_index, const char* value);
void AddDirectLinkEntries(); void AddDirectLinkEntries();
void AddLinkEntries(int depender_index, template <typename T>
std::vector<cmLinkItem> const& libs); void AddLinkEntries(int depender_index, std::vector<T> const& libs);
cmTarget const* FindTargetToLink(int depender_index, cmTarget const* FindTargetToLink(int depender_index,
const std::string& name); const std::string& name);

View File

@ -255,7 +255,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// A target should not depend on itself. // A target should not depend on itself.
emitted.insert(depender->GetName()); emitted.insert(depender->GetName());
for(std::vector<cmLinkItem>::const_iterator for(std::vector<cmLinkImplItem>::const_iterator
lib = impl->Libraries.begin(); lib = impl->Libraries.begin();
lib != impl->Libraries.end(); ++lib) lib != impl->Libraries.end(); ++lib)
{ {

View File

@ -799,13 +799,14 @@ static const char* targetPropertyTransitiveWhitelist[] = {
#undef TRANSITIVE_PROPERTY_NAME #undef TRANSITIVE_PROPERTY_NAME
std::string getLinkedTargetsContent( std::string
std::vector<cmTarget const*> &targets, getLinkedTargetsContent(
cmTarget const* target, std::vector<cmTarget const*> &targets,
cmTarget const* headTarget, cmTarget const* target,
cmGeneratorExpressionContext *context, cmTarget const* headTarget,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionContext *context,
const std::string &interfacePropertyName) cmGeneratorExpressionDAGChecker *dagChecker,
const std::string &interfacePropertyName)
{ {
cmGeneratorExpression ge(&context->Backtrace); cmGeneratorExpression ge(&context->Backtrace);
@ -841,15 +842,17 @@ std::string getLinkedTargetsContent(
return linkedTargetsContent; return linkedTargetsContent;
} }
std::string getLinkedTargetsContent(std::vector<cmLinkItem> const &libraries, std::string
cmTarget const* target, getLinkedTargetsContent(
cmTarget const* headTarget, std::vector<cmLinkImplItem> const &libraries,
cmGeneratorExpressionContext *context, cmTarget const* target,
cmGeneratorExpressionDAGChecker *dagChecker, cmTarget const* headTarget,
const std::string &interfacePropertyName) cmGeneratorExpressionContext *context,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string &interfacePropertyName)
{ {
std::vector<cmTarget const*> tgts; std::vector<cmTarget const*> tgts;
for (std::vector<cmLinkItem>::const_iterator for (std::vector<cmLinkImplItem>::const_iterator
it = libraries.begin(); it = libraries.begin();
it != libraries.end(); ++it) it != libraries.end(); ++it)
{ {

View File

@ -475,8 +475,8 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
} }
std::set<cmTarget const*> uniqueDeps; std::set<cmTarget const*> uniqueDeps;
for(std::vector<cmLinkItem>::const_iterator li = impl->Libraries.begin(); for(std::vector<cmLinkImplItem>::const_iterator
li != impl->Libraries.end(); ++li) li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{ {
cmTarget const* tgt = li->Target; cmTarget const* tgt = li->Target;
if (!tgt) if (!tgt)

View File

@ -165,14 +165,16 @@ public:
std::set<cmLinkItem> UtilityItems; std::set<cmLinkItem> UtilityItems;
bool UtilityItemsDone; bool UtilityItemsDone;
struct TargetPropertyEntry { class TargetPropertyEntry {
static cmLinkImplItem NoLinkImplItem;
public:
TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
const std::string &targetName = std::string()) cmLinkImplItem const& item = NoLinkImplItem)
: ge(cge), TargetName(targetName) : ge(cge), LinkImplItem(item)
{} {}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge; const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
std::vector<std::string> CachedEntries; std::vector<std::string> CachedEntries;
const std::string TargetName; cmLinkImplItem const& LinkImplItem;
}; };
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries; std::vector<TargetPropertyEntry*> CompileOptionsEntries;
@ -181,6 +183,10 @@ public:
std::vector<TargetPropertyEntry*> SourceEntries; std::vector<TargetPropertyEntry*> SourceEntries;
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries; std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
void AddInterfaceEntries(
cmTarget const* thisTarget, std::string const& config,
std::string const& prop, std::vector<TargetPropertyEntry*>& entries);
std::map<std::string, std::vector<TargetPropertyEntry*> > std::map<std::string, std::vector<TargetPropertyEntry*> >
CachedLinkInterfaceIncludeDirectoriesEntries; CachedLinkInterfaceIncludeDirectoriesEntries;
std::map<std::string, std::vector<TargetPropertyEntry*> > std::map<std::string, std::vector<TargetPropertyEntry*> >
@ -202,6 +208,8 @@ public:
std::map<std::string, bool> CacheLinkImplementationClosureDone; std::map<std::string, bool> CacheLinkImplementationClosureDone;
}; };
cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void deleteAndClear( void deleteAndClear(
std::vector<cmTargetInternals::TargetPropertyEntry*> &entries) std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
@ -770,45 +778,9 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
if (!this->Internal->CacheLinkInterfaceSourcesDone[config]) if (!this->Internal->CacheLinkInterfaceSourcesDone[config])
{ {
for (std::vector<cmValueWithOrigin>::const_iterator this->Internal->AddInterfaceEntries(
it = this->Internal->LinkImplementationPropertyEntries.begin(), this, config, "INTERFACE_SOURCES",
end = this->Internal->LinkImplementationPropertyEntries.end(); this->Internal->CachedLinkInterfaceSourcesEntries[config]);
it != end; ++it)
{
if (!cmGeneratorExpression::IsValidTargetName(it->Value)
&& cmGeneratorExpression::Find(it->Value) == std::string::npos)
{
continue;
}
{
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> 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 = "$<TARGET_PROPERTY:" +
it->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 = "$<$<BOOL:" + it->Value + ">:" + sourceGenex + ">";
}
cmGeneratorExpression ge(&it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
sourceGenex);
this->Internal
->CachedLinkInterfaceSourcesEntries[config].push_back(
new cmTargetInternals::TargetPropertyEntry(cge,
it->Value));
}
} }
std::vector<std::string>::size_type numFilesBefore = files.size(); std::vector<std::string>::size_type numFilesBefore = files.size();
@ -2044,6 +2016,10 @@ static void processIncludeDirectories(cmTarget const* tgt,
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it) 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 testIsOff = true;
bool cacheIncludes = false; bool cacheIncludes = false;
std::vector<std::string>& entryIncludes = (*it)->CachedEntries; std::vector<std::string>& entryIncludes = (*it)->CachedEntries;
@ -2069,36 +2045,12 @@ static void processIncludeDirectories(cmTarget const* tgt,
for(std::vector<std::string>::iterator for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li) li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{ {
std::string targetName = (*it)->TargetName; if (fromImported
std::string evaluatedTargetName;
{
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> 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)
&& !cmSystemTools::FileExists(li->c_str())) && !cmSystemTools::FileExists(li->c_str()))
{ {
cmOStringStream e; cmOStringStream e;
cmake::MessageType messageType = cmake::FATAL_ERROR; cmake::MessageType messageType = cmake::FATAL_ERROR;
if (fromEvaluatedImported) if (checkCMP0027)
{ {
switch(tgt->GetPolicyStatusCMP0027()) switch(tgt->GetPolicyStatusCMP0027())
{ {
@ -2238,50 +2190,14 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[config]) if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[config])
{ {
for (std::vector<cmValueWithOrigin>::const_iterator this->Internal->AddInterfaceEntries(
it = this->Internal->LinkImplementationPropertyEntries.begin(), this, config, "INTERFACE_INCLUDE_DIRECTORIES",
end = this->Internal->LinkImplementationPropertyEntries.end(); this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[config]);
it != end; ++it)
{
if (!cmGeneratorExpression::IsValidTargetName(it->Value)
&& cmGeneratorExpression::Find(it->Value) == std::string::npos)
{
continue;
}
{
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> 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 = "$<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(
includeGenex);
this->Internal
->CachedLinkInterfaceIncludeDirectoriesEntries[config].push_back(
new cmTargetInternals::TargetPropertyEntry(cge,
it->Value));
}
if(this->Makefile->IsOn("APPLE")) if(this->Makefile->IsOn("APPLE"))
{ {
LinkImplementation const* impl = this->GetLinkImplementation(config); LinkImplementation const* impl = this->GetLinkImplementation(config);
for(std::vector<cmLinkItem>::const_iterator for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin(); it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it) it != impl->Libraries.end(); ++it)
{ {
@ -2462,45 +2378,9 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[config]) if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[config])
{ {
for (std::vector<cmValueWithOrigin>::const_iterator this->Internal->AddInterfaceEntries(
it = this->Internal->LinkImplementationPropertyEntries.begin(), this, config, "INTERFACE_COMPILE_OPTIONS",
end = this->Internal->LinkImplementationPropertyEntries.end(); this->Internal->CachedLinkInterfaceCompileOptionsEntries[config]);
it != end; ++it)
{
if (!cmGeneratorExpression::IsValidTargetName(it->Value)
&& cmGeneratorExpression::Find(it->Value) == std::string::npos)
{
continue;
}
{
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> 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 = "$<TARGET_PROPERTY:" +
it->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 = "$<$<BOOL:" + it->Value + ">:" + optionGenex + ">";
}
cmGeneratorExpression ge(&it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
optionGenex);
this->Internal
->CachedLinkInterfaceCompileOptionsEntries[config].push_back(
new cmTargetInternals::TargetPropertyEntry(cge,
it->Value));
}
} }
processCompileOptions(this, processCompileOptions(this,
@ -2572,45 +2452,9 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[config]) if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[config])
{ {
for (std::vector<cmValueWithOrigin>::const_iterator this->Internal->AddInterfaceEntries(
it = this->Internal->LinkImplementationPropertyEntries.begin(), this, config, "INTERFACE_COMPILE_DEFINITIONS",
end = this->Internal->LinkImplementationPropertyEntries.end(); this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[config]);
it != end; ++it)
{
if (!cmGeneratorExpression::IsValidTargetName(it->Value)
&& cmGeneratorExpression::Find(it->Value) == std::string::npos)
{
continue;
}
{
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> 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 = "$<TARGET_PROPERTY:" +
it->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 = "$<$<BOOL:" + it->Value + ">:" + defsGenex + ">";
}
cmGeneratorExpression ge(&it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
defsGenex);
this->Internal
->CachedLinkInterfaceCompileDefinitionsEntries[config].push_back(
new cmTargetInternals::TargetPropertyEntry(cge,
it->Value));
}
if (!config.empty()) if (!config.empty())
{ {
std::string configPropName = "COMPILE_DEFINITIONS_" std::string configPropName = "COMPILE_DEFINITIONS_"
@ -2719,45 +2563,9 @@ void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[config]) if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[config])
{ {
for (std::vector<cmValueWithOrigin>::const_iterator this->Internal->AddInterfaceEntries(
it = this->Internal->LinkImplementationPropertyEntries.begin(), this, config, "INTERFACE_COMPILE_FEATURES",
end = this->Internal->LinkImplementationPropertyEntries.end(); this->Internal->CachedLinkInterfaceCompileFeaturesEntries[config]);
it != end; ++it)
{
if (!cmGeneratorExpression::IsValidTargetName(it->Value)
&& cmGeneratorExpression::Find(it->Value) == std::string::npos)
{
continue;
}
{
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> 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 = "$<TARGET_PROPERTY:" +
it->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 = "$<$<BOOL:" + it->Value + ">:" + featureGenex + ">";
}
cmGeneratorExpression ge(&it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
featureGenex);
this->Internal
->CachedLinkInterfaceCompileFeaturesEntries[config].push_back(
new cmTargetInternals::TargetPropertyEntry(cge,
it->Value));
}
} }
processCompileFeatures(this, processCompileFeatures(this,
@ -3675,7 +3483,8 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
// Add interface languages from linked targets. // Add interface languages from linked targets.
cmTargetCollectLinkLanguages cll(this, config, languages, this); cmTargetCollectLinkLanguages cll(this, config, languages, this);
for(std::vector<cmLinkItem>::const_iterator li = impl->Libraries.begin(); for(std::vector<cmLinkImplItem>::const_iterator
li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li) li != impl->Libraries.end(); ++li)
{ {
cll.Visit(*li); cll.Visit(*li);
@ -6242,7 +6051,8 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
cmTarget::LinkImplementation const* impl cmTarget::LinkImplementation const* impl
= this->GetLinkImplementationLibraries(config); = this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkItem>::const_iterator it = impl->Libraries.begin(); for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it) it != impl->Libraries.end(); ++it)
{ {
processILibs(config, this, *it, tgts , emitted); 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. // The link implementation is the default link interface.
LinkImplementation const* impl = LinkImplementation const* impl =
this->GetLinkImplementationLibrariesInternal(config, headTarget); 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 && if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
!this->Internal->PolicyWarnedCMP0022 && !usage_requirements_only) !this->Internal->PolicyWarnedCMP0022 && !usage_requirements_only)
{ {
@ -6397,12 +6208,12 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
headTarget, usage_requirements_only, headTarget, usage_requirements_only,
ifaceLibs); ifaceLibs);
} }
if (ifaceLibs != impl->Libraries) if (ifaceLibs != iface.Libraries)
{ {
std::string oldLibraries; std::string oldLibraries;
std::string newLibraries; std::string newLibraries;
const char *sep = ""; const char *sep = "";
for(std::vector<cmLinkItem>::const_iterator it for(std::vector<cmLinkImplItem>::const_iterator it
= impl->Libraries.begin(); it != impl->Libraries.end(); ++it) = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
{ {
oldLibraries += sep; oldLibraries += sep;
@ -6470,7 +6281,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
{ {
cmTarget::LinkImplementation const* impl = cmTarget::LinkImplementation const* impl =
thisTarget->GetLinkImplementation(config); thisTarget->GetLinkImplementation(config);
for(std::vector<cmLinkItem>::const_iterator for(std::vector<cmLinkImplItem>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{ {
if(emitted.insert(*li).second) if(emitted.insert(*li).second)
@ -6546,6 +6357,31 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
iface.Complete = true; iface.Complete = true;
} }
//----------------------------------------------------------------------------
void cmTargetInternals::AddInterfaceEntries(
cmTarget const* thisTarget, std::string const& config,
std::string const& prop, std::vector<TargetPropertyEntry*>& entries)
{
if(cmTarget::LinkImplementation const* impl =
thisTarget->GetLinkImplementationLibraries(config))
{
for (std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin(), end = impl->Libraries.end();
it != end; ++it)
{
if(it->Target)
{
std::string genex =
"$<TARGET_PROPERTY:" + *it + "," + prop + ">";
cmGeneratorExpression ge(&it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
entries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge, *it));
}
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTarget::LinkImplementation const* cmTarget::LinkImplementation const*
cmTarget::GetLinkImplementation(const std::string& config) const cmTarget::GetLinkImplementation(const std::string& config) const
@ -6621,12 +6457,9 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
cmGeneratorExpression ge(&le->Backtrace); cmGeneratorExpression ge(&le->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge = cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(le->Value); ge.Parse(le->Value);
cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, std::string const evaluated =
config, cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
false, cmSystemTools::ExpandListArgument(evaluated, llibs);
head,
&dagChecker),
llibs);
for(std::vector<std::string>::const_iterator li = llibs.begin(); for(std::vector<std::string>::const_iterator li = llibs.begin();
li != llibs.end(); ++li) li != llibs.end(); ++li)
@ -6674,7 +6507,8 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
// The entry is meant for this configuration. // The entry is meant for this configuration.
impl.Libraries.push_back( impl.Libraries.push_back(
cmLinkItem(name, this->FindTargetToLink(name))); cmLinkImplItem(name, this->FindTargetToLink(name),
le->Backtrace, evaluated != le->Value));
} }
std::set<std::string> const& seenProps = cge->GetSeenTargetProperties(); std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();

View File

@ -54,6 +54,20 @@ public:
cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {} cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
cmTarget const* 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: struct cmTargetLinkInformationMap:
public std::map<std::string, cmComputeLinkInformation*> public std::map<std::string, cmComputeLinkInformation*>
@ -296,7 +310,7 @@ public:
std::vector<std::string> Languages; std::vector<std::string> Languages;
// Libraries linked directly in this configuration. // Libraries linked directly in this configuration.
std::vector<cmLinkItem> Libraries; std::vector<cmLinkImplItem> Libraries;
// Libraries linked directly in other configurations. // Libraries linked directly in other configurations.
// Needed only for OLD behavior of CMP0003. // Needed only for OLD behavior of CMP0003.

View File

@ -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: CMake Debug Log:
Boolean compatibility of property "BOOL_PROP1" for target Boolean compatibility of property "BOOL_PROP1" for target
"CompatibleInterface" \(result: "TRUE"\): "CompatibleInterface" \(result: "TRUE"\):
@ -46,6 +39,13 @@ CMake Debug Log:
\* Target "iface1" property value "FALSE" \(Interface set\) \* Target "iface1" property value "FALSE" \(Interface set\)
\* Target "iface2" property value "FALSE" \(Agree\) \* 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: CMake Debug Log:
String compatibility of property "STRING_PROP1" for target String compatibility of property "STRING_PROP1" for target
"CompatibleInterface" \(result: "prop1"\): "CompatibleInterface" \(result: "prop1"\):

View File

@ -1,7 +1,9 @@
CMake Error: CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:LINKER_LANGUAGE> \$<TARGET_PROPERTY:LINKER_LANGUAGE>
LINKER_LANGUAGE target property can not be used while evaluating link 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\)

View File

@ -1,7 +1,9 @@
CMake Error: CMake Error at link-libraries-TARGET_FILE-genex.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_FILE:foo> \$<TARGET_FILE:foo>
Expressions which require the linker language may not be used while Expressions which require the linker language may not be used while
evaluating link libraries evaluating link libraries
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)