summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalVisualStudioGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalVisualStudioGenerator.cxx')
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx193
1 files changed, 57 insertions, 136 deletions
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index e8a00bb..bae18a3 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -89,9 +89,6 @@ void cmGlobalVisualStudioGenerator::Generate()
}
}
- // Fix utility dependencies to avoid linking to libraries.
- this->FixUtilityDepends();
-
// Configure CMake Visual Studio macros, for this user on this version
// of Visual Studio.
this->ConfigureCMakeVisualStudioMacros();
@@ -240,129 +237,59 @@ std::string cmGlobalVisualStudioGenerator::GetUserMacrosRegKeyBase()
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::FixUtilityDepends()
+bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
{
- // Skip for VS versions 8 and above.
- if(!this->VSLinksDependencies())
+ if(!this->cmGlobalGenerator::ComputeTargetDepends())
{
- return;
+ return false;
}
-
- // For VS versions before 8:
- //
- // When a target that links contains a project-level dependency on a
- // library target that library is automatically linked. In order to
- // allow utility-style project-level dependencies that do not
- // actually link we need to automatically insert an intermediate
- // custom target.
- //
- // Here we edit the utility dependencies of a target to add the
- // intermediate custom target when necessary.
- for(unsigned i = 0; i < this->LocalGenerators.size(); ++i)
+ std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
- cmTargets* targets =
- &(this->LocalGenerators[i]->GetMakefile()->GetTargets());
- for(cmTargets::iterator tarIt = targets->begin();
- tarIt != targets->end(); ++tarIt)
+ std::vector<cmLocalGenerator*>& gen = it->second;
+ for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
+ i != gen.end(); ++i)
{
- this->FixUtilityDependsForTarget(tarIt->second);
+ cmTargets& targets = (*i)->GetMakefile()->GetTargets();
+ for(cmTargets::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ this->ComputeVSTargetDepends(ti->second);
+ }
}
}
+ return true;
}
//----------------------------------------------------------------------------
-void
-cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget(cmTarget& target)
+void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
{
- // Only targets that link need to be fixed.
- if(target.GetType() != cmTarget::STATIC_LIBRARY &&
- target.GetType() != cmTarget::SHARED_LIBRARY &&
- target.GetType() != cmTarget::MODULE_LIBRARY &&
- target.GetType() != cmTarget::EXECUTABLE)
+ if(this->VSTargetDepends.find(&target) != this->VSTargetDepends.end())
{
return;
}
-
-#if 0
- // This feature makes a mess in SLN files for VS 7.1 and below. It
- // creates an extra target for every target that is "linked" by a
- // static library. Without this feature static libraries do not
- // wait until their "link" dependencies are built to build. This is
- // not a problem 99.9% of the time, and projects that do have the
- // problem can enable this work-around by using add_dependencies.
-
- // Static libraries cannot depend directly on the targets to which
- // they link because VS will copy those targets into the library
- // (for VS < 8). To work around the problem we copy the
- // dependencies to be utility dependencies so that the work-around
- // below is used.
- if(target.GetType() == cmTarget::STATIC_LIBRARY)
+ VSDependSet& vsTargetDepend = this->VSTargetDepends[&target];
+ if(target.GetType() != cmTarget::STATIC_LIBRARY)
{
cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator i = libs.begin();
- i != libs.end(); ++i)
+ for(cmTarget::LinkLibraryVectorType::const_iterator j = libs.begin();
+ j != libs.end(); ++j)
{
- if(cmTarget* depTarget = this->FindTarget(0, i->first.c_str(), false))
+ if(j->first != target.GetName() &&
+ this->FindTarget(0, j->first.c_str()))
{
- target.AddUtility(depTarget->GetName());
- }
- }
- }
-#endif
-
- // Look at each utility dependency.
- for(std::set<cmStdString>::const_iterator ui =
- target.GetUtilities().begin();
- ui != target.GetUtilities().end(); ++ui)
- {
- if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
- {
- if(depTarget->GetType() == cmTarget::STATIC_LIBRARY ||
- depTarget->GetType() == cmTarget::SHARED_LIBRARY ||
- depTarget->GetType() == cmTarget::MODULE_LIBRARY)
- {
- // This utility dependency will cause an attempt to link. If
- // the depender does not already link the dependee we need an
- // intermediate target.
- if(!this->CheckTargetLinks(target, ui->c_str()))
- {
- this->CreateUtilityDependTarget(*depTarget);
- }
+ vsTargetDepend.insert(j->first);
}
}
}
-}
-
-//----------------------------------------------------------------------------
-void
-cmGlobalVisualStudioGenerator::CreateUtilityDependTarget(cmTarget& target)
-{
- // This target is a library on which a utility dependency exists.
- // We need to create an intermediate custom target to hook up the
- // dependency without causing a link.
- const char* altName = target.GetProperty("ALTERNATIVE_DEPENDENCY_NAME");
- if(!altName)
+ std::set<cmStdString> const& utils = target.GetUtilities();
+ for(std::set<cmStdString>::const_iterator i = utils.begin();
+ i != utils.end(); ++i)
{
- // Create the intermediate utility target.
- std::string altNameStr = target.GetName();
- altNameStr += "_UTILITY";
- const std::vector<std::string> no_depends;
- cmCustomCommandLines no_commands;
- const char* no_working_dir = 0;
- const char* no_comment = 0;
- target.GetMakefile()->AddUtilityCommand(altNameStr.c_str(), true,
- no_working_dir, no_depends,
- no_commands, false, no_comment);
- target.SetProperty("ALTERNATIVE_DEPENDENCY_NAME", altNameStr.c_str());
-
- // Most targets have a GUID created in ConfigureFinalPass. Since
- // that has already been called, create one for this target now.
- this->CreateGUID(altNameStr.c_str());
-
- // The intermediate target should depend on the original target.
- if(cmTarget* alt = this->FindTarget(0, altNameStr.c_str()))
+ if(*i != target.GetName())
{
- alt->AddUtility(target.GetName());
+ std::string name = this->GetUtilityForTarget(target, i->c_str());
+ vsTargetDepend.insert(name);
}
}
}
@@ -390,10 +317,28 @@ bool cmGlobalVisualStudioGenerator::CheckTargetLinks(cmTarget& target,
}
//----------------------------------------------------------------------------
-const char*
+std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget* target)
+{
+ UtilityDependsMap::iterator i = this->UtilityDepends.find(target);
+ if(i == this->UtilityDepends.end())
+ {
+ std::string name = this->WriteUtilityDepend(target);
+ UtilityDependsMap::value_type entry(target, name);
+ i = this->UtilityDepends.insert(entry).first;
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+std::string
cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
const char* name)
{
+ if(!this->VSLinksDependencies())
+ {
+ return name;
+ }
+
// Possibly depend on an intermediate utility target to avoid
// linking.
if(target.GetType() == cmTarget::STATIC_LIBRARY ||
@@ -401,19 +346,19 @@ cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
target.GetType() == cmTarget::MODULE_LIBRARY ||
target.GetType() == cmTarget::EXECUTABLE)
{
- // The depender is a target that links. Lookup the dependee to
- // see if it provides an alternative dependency name.
+ // The depender is a target that links.
if(cmTarget* depTarget = this->FindTarget(0, name))
{
- // Check for an alternative name created by FixUtilityDepends.
- if(const char* altName =
- depTarget->GetProperty("ALTERNATIVE_DEPENDENCY_NAME"))
+ if(depTarget->GetType() == cmTarget::STATIC_LIBRARY ||
+ depTarget->GetType() == cmTarget::SHARED_LIBRARY ||
+ depTarget->GetType() == cmTarget::MODULE_LIBRARY)
{
- // The alternative name is needed only if the depender does
- // not really link to the dependee.
+ // This utility dependency will cause an attempt to link. If
+ // the depender does not already link the dependee we need an
+ // intermediate target.
if(!this->CheckTargetLinks(target, name))
{
- return altName;
+ return this->GetUtilityDepend(depTarget);
}
}
}
@@ -424,30 +369,6 @@ cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::GetTargetSets(
- TargetDependSet& projectTargets, TargetDependSet& originalTargets,
- cmLocalGenerator* root, GeneratorVector const& generators
- )
-{
- this->cmGlobalGenerator::GetTargetSets(projectTargets, originalTargets,
- root, generators);
-
- // Add alternative dependency targets created by FixUtilityDepends.
- for(TargetDependSet::iterator ti = projectTargets.begin();
- ti != projectTargets.end(); ++ti)
- {
- cmTarget* tgt = *ti;
- if(const char* altName = tgt->GetProperty("ALTERNATIVE_DEPENDENCY_NAME"))
- {
- if(cmTarget* alt = tgt->GetMakefile()->FindTarget(altName))
- {
- projectTargets.insert(alt);
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
#include <windows.h>
//----------------------------------------------------------------------------