Cache context-independent includes on evaluation.

Generator expressions whose output depends on the configuration
now record that fact. The GetIncludeDirectories method can use
that result to cache the include directories for later calls.

GetIncludeDirectories is called multiple times for a target
for each configuration, so this should restore performance for
multi-config generators.
This commit is contained in:
Stephen Kelly 2013-02-03 07:33:15 +01:00
parent 089fe1c13d
commit e48d84209c
5 changed files with 66 additions and 14 deletions

View File

@ -88,6 +88,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
context.Config = config;
context.Quiet = quiet;
context.HadError = false;
context.HadContextSensitiveCondition = false;
context.HeadTarget = headTarget;
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
context.Backtrace = this->Backtrace;
@ -109,6 +110,10 @@ const char *cmCompiledGeneratorExpression::Evaluate(
break;
}
}
if (!context.HadError)
{
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
}
this->Targets = context.Targets;
// TODO: Return a std::string from here instead?
@ -118,7 +123,8 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace,
const char *input)
: Backtrace(backtrace), Input(input ? input : "")
: Backtrace(backtrace), Input(input ? input : ""),
HadContextSensitiveCondition(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens =

View File

@ -100,6 +100,10 @@ public:
{
return this->Backtrace;
}
bool GetHadContextSensitiveCondition() const
{
return this->HadContextSensitiveCondition;
}
private:
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
@ -118,6 +122,7 @@ private:
mutable std::set<cmTarget*> Targets;
mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
};
#endif

View File

@ -238,6 +238,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent *,
cmGeneratorExpressionDAGChecker *) const
{
context->HadContextSensitiveCondition = true;
return context->Config ? context->Config : "";
}
} configurationNode;
@ -262,6 +263,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
"Expression syntax not recognized.");
return std::string();
}
context->HadContextSensitiveCondition = true;
if (!context->Config)
{
return parameters.front().empty() ? "1" : "0";
@ -455,12 +457,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
if (propertyName == "POSITION_INDEPENDENT_CODE")
{
context->HadContextSensitiveCondition = true;
return target->GetLinkInterfaceDependentBoolProperty(
"POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
}
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
context->Config))
{
context->HadContextSensitiveCondition = true;
return target->GetLinkInterfaceDependentBoolProperty(
propertyName,
context->Config) ? "1" : "0";
@ -468,6 +472,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (target->IsLinkInterfaceDependentStringProperty(propertyName,
context->Config))
{
context->HadContextSensitiveCondition = true;
const char *propContent =
target->GetLinkInterfaceDependentStringProperty(
propertyName,
@ -486,12 +491,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (targetPropertyTransitiveWhitelist[i] == propertyName)
{
cmGeneratorExpression ge(context->Backtrace);
return ge.Parse(prop)->Evaluate(context->Makefile,
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
std::string result = cge->Evaluate(context->Makefile,
context->Config,
context->Quiet,
context->HeadTarget,
target,
&dagChecker);
if (cge->GetHadContextSensitiveCondition())
{
context->HadContextSensitiveCondition = true;
}
return result;
}
}
return prop;
@ -585,6 +597,9 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
"be used with add_custom_command.");
return std::string();
}
context->HadContextSensitiveCondition = true;
for (size_t i = 0;
i < (sizeof(targetPolicyWhitelist) /
sizeof(*targetPolicyWhitelist));
@ -716,12 +731,18 @@ private:
}
cmGeneratorExpression ge(context->Backtrace);
return ge.Parse(propContent)->Evaluate(context->Makefile,
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent);
std::string result = cge->Evaluate(context->Makefile,
context->Config,
context->Quiet,
context->HeadTarget,
target,
&dagChecker);
if (cge->GetHadContextSensitiveCondition())
{
context->HadContextSensitiveCondition = true;
}
return result;
}
} linkedNode;

View File

@ -32,6 +32,7 @@ struct cmGeneratorExpressionContext
// directly or indirectly in the property.
bool Quiet;
bool HadError;
bool HadContextSensitiveCondition;
};
struct cmGeneratorExpressionDAGChecker;

View File

@ -134,6 +134,7 @@ public:
: ge(cge)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
std::vector<std::string> CachedIncludes;
};
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
};
@ -2778,22 +2779,36 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
end = this->Internal->IncludeDirectoriesEntries.end();
it != end; ++it)
{
std::vector<std::string> entryIncludes;
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker),
entryIncludes);
bool testIsOff = true;
bool cacheIncludes = false;
std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
if(!entryIncludes.empty())
{
testIsOff = false;
}
else
{
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker),
entryIncludes);
if (!(*it)->ge->GetHadContextSensitiveCondition())
{
cacheIncludes = true;
}
}
std::string usedIncludes;
for(std::vector<std::string>::const_iterator
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
std::string inc = *li;
if (!cmSystemTools::IsOff(inc.c_str()))
if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
{
cmSystemTools::ConvertToUnixSlashes(inc);
cmSystemTools::ConvertToUnixSlashes(*li);
}
std::string inc = *li;
if(uniqueIncludes.insert(inc).second)
{
@ -2804,6 +2819,10 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
}
}
}
if (cacheIncludes)
{
(*it)->CachedIncludes = entryIncludes;
}
if (!usedIncludes.empty())
{
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,