diff options
author | Brad King <brad.king@kitware.com> | 2007-12-22 18:08:26 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2007-12-22 18:08:26 (GMT) |
commit | 2836fc43e79cd5497f2e63ae091ca67f1cb2485d (patch) | |
tree | 3a402127b3f839adb22b6d1ceed43809da3df461 /Source/cmGlobalUnixMakefileGenerator3.cxx | |
parent | bfeeb88b1f32086885ee02974bf54c28b0a4b9ab (diff) | |
download | CMake-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.cxx | 83 |
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; +} |