summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-02-01 08:38:40 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-02-02 14:06:53 (GMT)
commit089fe1c13d8fa73be5182162a855c17351d1f918 (patch)
tree288b2e9576fff37aee787df74075dfe9ebbe6155
parent179f49560286e2e322b9b0cf5d0a277b7634540f (diff)
downloadCMake-089fe1c13d8fa73be5182162a855c17351d1f918.zip
CMake-089fe1c13d8fa73be5182162a855c17351d1f918.tar.gz
CMake-089fe1c13d8fa73be5182162a855c17351d1f918.tar.bz2
Optimize genex evaluation for includes and defines.
While porting boost to use these features, the generation step took too long (several minutes before I stopped it). The reason was that the boost libraries form a large interdependent mesh. The libraries list their dependencies in their INTERFACE such as: $<LINKED:boost::core>;$<LINKED:boost::config>;$<LINKED:boost::mpl> As boost::core already depends on the boost::config libraries, that expression has no impact on the end-content, as it is removed after the generation step. There is no DAG issue though, so the generator expression evaluation would fully evaluate them. In the case of the config library, it also depends on the core library, so all depends are followed through that again, despite the fact that they've just been evaluated. After this patch, the evaluation skips libraries if they have already been seen via depends or directly in the content. This patch keeps track of targets whose INTERFACE has been consumed already. The INCLUDE_DIRECTORIES and COMPILE_DEFINITIONS properties are whitelisted because repeated content will be stripped out later during generation. For other properties now and in the future, that may not be the case.
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx26
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx6
3 files changed, 35 insertions, 1 deletions
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index bcb0820..b9069ef 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -24,7 +24,33 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
: Parent(parent), Target(target), Property(property),
Content(content), Backtrace(backtrace)
{
+ const cmGeneratorExpressionDAGChecker *top = this;
+ const cmGeneratorExpressionDAGChecker *p = this->Parent;
+ while (p)
+ {
+ top = p;
+ p = p->Parent;
+ }
this->CheckResult = this->checkGraph();
+
+ if (CheckResult == DAG && (top->Property == "INCLUDE_DIRECTORIES"
+ || top->Property == "COMPILE_DEFINITIONS") )
+ {
+ std::map<cmStdString, std::set<cmStdString> >::const_iterator it
+ = top->Seen.find(target);
+ if (it != top->Seen.end())
+ {
+ const std::set<cmStdString> &propSet = it->second;
+ const std::set<cmStdString>::const_iterator i = propSet.find(property);
+ if (i != propSet.end())
+ {
+ this->CheckResult = ALREADY_SEEN;
+ return;
+ }
+ }
+ const_cast<cmGeneratorExpressionDAGChecker *>(top)
+ ->Seen[target].insert(property);
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 7e9c62a..a2e5ce4 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -28,7 +28,8 @@ struct cmGeneratorExpressionDAGChecker
enum Result {
DAG,
SELF_REFERENCE,
- CYCLIC_REFERENCE
+ CYCLIC_REFERENCE,
+ ALREADY_SEEN
};
Result check() const;
@@ -47,6 +48,7 @@ private:
const cmGeneratorExpressionDAGChecker * const Parent;
const std::string Target;
const std::string Property;
+ std::map<cmStdString, std::set<cmStdString> > Seen;
const GeneratorExpressionContent * const Content;
const cmListFileBacktrace Backtrace;
Result CheckResult;
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index cbea1d9..cd4b7d8 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -435,6 +435,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
return std::string();
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We're not going to find anything new here.
+ return std::string();
case cmGeneratorExpressionDAGChecker::DAG:
break;
}
@@ -705,6 +708,9 @@ private:
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
return std::string();
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We're not going to find anything new here.
+ return std::string();
case cmGeneratorExpressionDAGChecker::DAG:
break;
}