Merge topic 'refactor-usage-requirement-evaluation'
93790506
cmTarget: Simplify INTERFACE_INCLUDE_DIRECTORIES usage requirement lookupb5b098eb
cmTarget: Simplify CMP0027 logic in processIncludeDirectories5e07dcf7
cmTarget: Add to LinkImplementation whether each library was a genexf77b384c
cmTarget: Simplify INTERFACE_COMPILE_FEATURES usage requirement lookup61ef8daa
cmTarget: Simplify INTERFACE_COMPILE_DEFINITIONS usage requirement lookupd9586f83
cmTarget: Simplify INTERFACE_COMPILE_OPTIONS usage requirement lookup3156275b
cmTarget: Simplify INTERFACE_SOURCES usage requirement lookup363cd33e
cmTarget: Add method to add usage requirements from linked interfaces251e835b
cmTarget: Add to LinkImplementation a backtrace for each library848c8ccf
cmTarget: Refactor LinkImplementation to allow more informationf85ccf23
cmGeneratorExpressionEvaluator: Shorten some long lines82e91e34
cmComputeLinkDepends: Convert AddLinkEntries to a template
This commit is contained in:
commit
61be345115
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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"\):
|
||||||
|
|
|
@ -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\)
|
||||||
|
|
|
@ -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\)
|
||||||
|
|
Loading…
Reference in New Issue