summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalUnixMakefileGenerator3.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2007-12-22 18:08:26 (GMT)
committerBrad King <brad.king@kitware.com>2007-12-22 18:08:26 (GMT)
commit2836fc43e79cd5497f2e63ae091ca67f1cb2485d (patch)
tree3a402127b3f839adb22b6d1ceed43809da3df461 /Source/cmGlobalUnixMakefileGenerator3.cxx
parentbfeeb88b1f32086885ee02974bf54c28b0a4b9ab (diff)
downloadCMake-2836fc43e79cd5497f2e63ae091ca67f1cb2485d.zip
CMake-2836fc43e79cd5497f2e63ae091ca67f1cb2485d.tar.gz
CMake-2836fc43e79cd5497f2e63ae091ca67f1cb2485d.tar.bz2
BUG: Support cyclic dependencies among STATIC libraries by removing one from the generated Makefile rules.
Diffstat (limited to 'Source/cmGlobalUnixMakefileGenerator3.cxx')
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx83
1 files changed, 82 insertions, 1 deletions
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index a0b1c2a..792ee56 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -905,7 +905,8 @@ cmGlobalUnixMakefileGenerator3
emitted.insert(target.GetName());
// Loop over all library dependencies.
- const cmTarget::LinkLibraryVectorType& tlibs = target.GetLinkLibraries();
+ const cmTarget::LinkLibraryVectorType&
+ tlibs = target.GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
lib != tlibs.end(); ++lib)
{
@@ -960,6 +961,13 @@ cmGlobalUnixMakefileGenerator3
// if a match was found then ...
if (result)
{
+ // Avoid creating cyclic dependencies.
+ if(!this->AllowTargetDepends(&target, result))
+ {
+ return;
+ }
+
+ // Create the target-level dependency.
std::string tgtName = lg3->GetRelativeTargetDirectory(*result);
tgtName += "/all";
depends.push_back(tgtName);
@@ -1049,3 +1057,76 @@ bool cmGlobalUnixMakefileGenerator3
}
return false;
}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalUnixMakefileGenerator3
+::AllowTargetDepends(cmTarget const* depender, cmTarget const* dependee)
+{
+ // Check whether the depender is among the dependee's dependencies.
+ std::vector<cmTarget const*> steps;
+ if(this->FindDependency(depender, dependee, steps))
+ {
+ // This creates a cyclic dependency.
+ bool isStatic = depender->GetType() == cmTarget::STATIC_LIBRARY;
+ cmOStringStream e;
+ e << "Cyclic dependency among targets:\n"
+ << " " << depender->GetName() << "\n";
+ for(unsigned int i = static_cast<unsigned int>(steps.size());
+ i > 0; --i)
+ {
+ cmTarget const* step = steps[i-1];
+ e << " -> " << step->GetName() << "\n";
+ isStatic = isStatic && step->GetType() == cmTarget::STATIC_LIBRARY;
+ }
+ if(isStatic)
+ {
+ e << " All targets are STATIC libraries.\n";
+ e << " Dropping "
+ << depender->GetName() << " -> " << dependee->GetName()
+ << " to resolve.\n";
+ cmSystemTools::Message(e.str().c_str());
+ }
+ else
+ {
+ e << " At least one target is not a STATIC library.\n";
+ cmSystemTools::Error(e.str().c_str());
+ }
+ return false;
+ }
+ else
+ {
+ // This does not create a cyclic dependency.
+ this->TargetDependencies[depender].insert(dependee);
+ return true;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalUnixMakefileGenerator3
+::FindDependency(cmTarget const* goal, cmTarget const* current,
+ std::vector<cmTarget const*>& steps)
+{
+ if(current == goal)
+ {
+ steps.push_back(current);
+ return true;
+ }
+ TargetDependMap::const_iterator i = this->TargetDependencies.find(current);
+ if(i == this->TargetDependencies.end())
+ {
+ return false;
+ }
+ TargetDependSet const& depends = i->second;
+ for(TargetDependSet::const_iterator j = depends.begin();
+ j != depends.end(); ++j)
+ {
+ if(this->FindDependency(goal, *j, steps))
+ {
+ steps.push_back(current);
+ return true;
+ }
+ }
+ return false;
+}