Merge topic 'vs-utility-depends'
a99f620
Fix unused parameter warning in VS 7.1 generator79a88c3
Refactor VS <= 7.1 utility-depends workaround325bdb2
Factor out duplicate VS target dependency code6bea843
Factor out global generator ComputeTargetDepends method
This commit is contained in:
commit
6c155d9e9e
|
@ -863,19 +863,10 @@ void cmGlobalGenerator::Generate()
|
|||
}
|
||||
|
||||
// Compute the inter-target dependencies.
|
||||
{
|
||||
cmComputeTargetDepends ctd(this);
|
||||
if(!ctd.Compute())
|
||||
if(!this->ComputeTargetDepends())
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::vector<cmTarget*> const& targets = ctd.GetTargets();
|
||||
for(std::vector<cmTarget*>::const_iterator ti = targets.begin();
|
||||
ti != targets.end(); ++ti)
|
||||
{
|
||||
ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a map from local generator to the complete set of targets
|
||||
// it builds by default.
|
||||
|
@ -907,6 +898,23 @@ void cmGlobalGenerator::Generate()
|
|||
this->CMakeInstance->UpdateProgress("Generating done", -1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGlobalGenerator::ComputeTargetDepends()
|
||||
{
|
||||
cmComputeTargetDepends ctd(this);
|
||||
if(!ctd.Compute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::vector<cmTarget*> const& targets = ctd.GetTargets();
|
||||
for(std::vector<cmTarget*>::const_iterator ti = targets.begin();
|
||||
ti != targets.end(); ++ti)
|
||||
{
|
||||
ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGlobalGenerator::CheckTargets()
|
||||
{
|
||||
|
|
|
@ -275,6 +275,8 @@ protected:
|
|||
void SetLanguageEnabledMaps(const char* l, cmMakefile* mf);
|
||||
void FillExtensionToLanguageMap(const char* l, cmMakefile* mf);
|
||||
|
||||
virtual bool ComputeTargetDepends();
|
||||
|
||||
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS();
|
||||
|
||||
bool CheckTargets();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "cmLocalVisualStudio6Generator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmake.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
|
||||
// Utility function to make a valid VS6 *.dsp filename out
|
||||
// of a CMake target name:
|
||||
|
@ -274,44 +275,33 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
|
|||
fout << "Package=<5>\n{{{\n}}}\n\n";
|
||||
fout << "Package=<4>\n";
|
||||
fout << "{{{\n";
|
||||
|
||||
// insert Begin Project Dependency Project_Dep_Name project stuff here
|
||||
if (target.GetType() != cmTarget::STATIC_LIBRARY)
|
||||
{
|
||||
cmTarget::LinkLibraryVectorType::const_iterator j, jend;
|
||||
j = target.GetLinkLibraries().begin();
|
||||
jend = target.GetLinkLibraries().end();
|
||||
for(;j!= jend; ++j)
|
||||
{
|
||||
if(j->first != dspname)
|
||||
{
|
||||
// is the library part of this DSW ? If so add dependency
|
||||
if(this->FindTarget(0, j->first.c_str()))
|
||||
VSDependSet const& depends = this->VSTargetDepends[&target];
|
||||
for(VSDependSet::const_iterator di = depends.begin();
|
||||
di != depends.end(); ++di)
|
||||
{
|
||||
const char* name = di->c_str();
|
||||
fout << "Begin Project Dependency\n";
|
||||
fout << "Project_Dep_Name "
|
||||
<< GetVS6TargetName(j->first.c_str()) << "\n";
|
||||
fout << "Project_Dep_Name " << GetVS6TargetName(name) << "\n";
|
||||
fout << "End Project Dependency\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<cmStdString>::const_iterator i, end;
|
||||
// write utility dependencies.
|
||||
i = target.GetUtilities().begin();
|
||||
end = target.GetUtilities().end();
|
||||
for(;i!= end; ++i)
|
||||
{
|
||||
if(*i != dspname)
|
||||
{
|
||||
std::string depName = this->GetUtilityForTarget(target, i->c_str());
|
||||
fout << "Begin Project Dependency\n";
|
||||
fout << "Project_Dep_Name " << GetVS6TargetName(depName) << "\n";
|
||||
fout << "End Project Dependency\n";
|
||||
}
|
||||
}
|
||||
fout << "}}}\n\n";
|
||||
|
||||
UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
|
||||
if(ui != this->UtilityDepends.end())
|
||||
{
|
||||
const char* uname = ui->second.c_str();
|
||||
fout << "Project: \"" << uname << "\"="
|
||||
<< dir << "\\" << uname << ".dsp - Package Owner=<4>\n\n";
|
||||
fout <<
|
||||
"Package=<5>\n{{{\n}}}\n\n"
|
||||
"Package=<4>\n"
|
||||
"{{{\n"
|
||||
"Begin Project Dependency\n"
|
||||
"Project_Dep_Name " << dspname << "\n"
|
||||
"End Project Dependency\n"
|
||||
"}}}\n\n";
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -367,6 +357,49 @@ void cmGlobalVisualStudio6Generator::WriteDSWHeader(std::ostream& fout)
|
|||
fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmGlobalVisualStudio6Generator::WriteUtilityDepend(cmTarget* target)
|
||||
{
|
||||
std::string pname = target->GetName();
|
||||
pname += "_UTILITY";
|
||||
pname = GetVS6TargetName(pname.c_str());
|
||||
std::string fname = target->GetMakefile()->GetStartOutputDirectory();
|
||||
fname += "/";
|
||||
fname += pname;
|
||||
fname += ".dsp";
|
||||
cmGeneratedFileStream fout(fname.c_str());
|
||||
fout.SetCopyIfDifferent(true);
|
||||
fout <<
|
||||
"# Microsoft Developer Studio Project File - Name=\""
|
||||
<< pname << "\" - Package Owner=<4>\n"
|
||||
"# Microsoft Developer Studio Generated Build File, Format Version 6.00\n"
|
||||
"# ** DO NOT EDIT **\n"
|
||||
"\n"
|
||||
"# TARGTYPE \"Win32 (x86) Generic Project\" 0x010a\n"
|
||||
"\n"
|
||||
"CFG=" << pname << " - Win32 Debug\n"
|
||||
"!MESSAGE \"" << pname << " - Win32 Debug\""
|
||||
" (based on \"Win32 (x86) Generic Project\")\n"
|
||||
"!MESSAGE \"" << pname << " - Win32 Release\" "
|
||||
"(based on \"Win32 (x86) Generic Project\")\n"
|
||||
"!MESSAGE \"" << pname << " - Win32 MinSizeRel\" "
|
||||
"(based on \"Win32 (x86) Generic Project\")\n"
|
||||
"!MESSAGE \"" << pname << " - Win32 RelWithDebInfo\" "
|
||||
"(based on \"Win32 (x86) Generic Project\")\n"
|
||||
"\n"
|
||||
"# Begin Project\n"
|
||||
"# Begin Target\n"
|
||||
"# Name \"" << pname << " - Win32 Debug\"\n"
|
||||
"# Name \"" << pname << " - Win32 Release\"\n"
|
||||
"# Name \"" << pname << " - Win32 MinSizeRel\"\n"
|
||||
"# Name \"" << pname << " - Win32 RelWithDebInfo\"\n"
|
||||
"# End Target\n"
|
||||
"# End Project\n"
|
||||
;
|
||||
return pname;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalVisualStudio6Generator
|
||||
::GetDocumentation(cmDocumentationEntry& entry) const
|
||||
|
|
|
@ -96,6 +96,7 @@ private:
|
|||
const char* name, const char* path,
|
||||
const std::set<cmStdString>& dependencies);
|
||||
void WriteDSWFooter(std::ostream& fout);
|
||||
virtual std::string WriteUtilityDepend(cmTarget* target);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -163,16 +163,31 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
|
|||
ext = targetExt;
|
||||
}
|
||||
|
||||
std::string guid = this->GetGUID(dspname);
|
||||
fout << project
|
||||
<< dspname << "\", \""
|
||||
<< this->ConvertToSolutionPath(dir)
|
||||
<< "\\" << dspname << ext << "\", \"{"
|
||||
<< this->GetGUID(dspname) << "}\"\n";
|
||||
<< "\\" << dspname << ext << "\", \"{" << guid << "}\"\n";
|
||||
fout << "\tProjectSection(ProjectDependencies) = postProject\n";
|
||||
this->WriteProjectDepends(fout, dspname, dir, t);
|
||||
fout << "\tEndProjectSection\n";
|
||||
|
||||
fout <<"EndProject\n";
|
||||
|
||||
UtilityDependsMap::iterator ui = this->UtilityDepends.find(&t);
|
||||
if(ui != this->UtilityDepends.end())
|
||||
{
|
||||
const char* uname = ui->second.c_str();
|
||||
fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
|
||||
<< uname << "\", \""
|
||||
<< this->ConvertToSolutionPath(dir)
|
||||
<< "\\" << uname << ".vcproj" << "\", \"{"
|
||||
<< this->GetGUID(uname) << "}\"\n"
|
||||
<< "\tProjectSection(ProjectDependencies) = postProject\n"
|
||||
<< "\t\t{" << guid << "} = {" << guid << "}\n"
|
||||
<< "\tEndProjectSection\n"
|
||||
<< "EndProject\n";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -182,51 +197,15 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
|
|||
void
|
||||
cmGlobalVisualStudio71Generator
|
||||
::WriteProjectDepends(std::ostream& fout,
|
||||
const char* dspname,
|
||||
const char*,
|
||||
const char*, cmTarget& target)
|
||||
{
|
||||
#if 0
|
||||
// Create inter-target dependencies in the solution file. For VS
|
||||
// 7.1 and below we cannot let static libraries depend directly on
|
||||
// targets to which they "link" because the librarian tool will copy
|
||||
// the targets into the static library. See
|
||||
// cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget for a
|
||||
// work-around. VS 8 and above do not have this problem.
|
||||
if (!this->VSLinksDependencies() ||
|
||||
target.GetType() != cmTarget::STATIC_LIBRARY);
|
||||
#else
|
||||
if (target.GetType() != cmTarget::STATIC_LIBRARY)
|
||||
#endif
|
||||
VSDependSet const& depends = this->VSTargetDepends[&target];
|
||||
for(VSDependSet::const_iterator di = depends.begin();
|
||||
di != depends.end(); ++di)
|
||||
{
|
||||
cmTarget::LinkLibraryVectorType::const_iterator j, jend;
|
||||
j = target.GetLinkLibraries().begin();
|
||||
jend = target.GetLinkLibraries().end();
|
||||
for(;j!= jend; ++j)
|
||||
{
|
||||
if(j->first != dspname)
|
||||
{
|
||||
// is the library part of this SLN ? If so add dependency
|
||||
// find target anywhere because all depend libraries are
|
||||
// brought in as well
|
||||
if(this->FindTarget(0, j->first.c_str()))
|
||||
{
|
||||
fout << "\t\t{" << this->GetGUID(j->first.c_str()) << "} = {"
|
||||
<< this->GetGUID(j->first.c_str()) << "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<cmStdString>::const_iterator i, end;
|
||||
// write utility dependencies.
|
||||
i = target.GetUtilities().begin();
|
||||
end = target.GetUtilities().end();
|
||||
for(;i!= end; ++i)
|
||||
{
|
||||
if(*i != dspname)
|
||||
{
|
||||
std::string name = this->GetUtilityForTarget(target, i->c_str());
|
||||
std::string guid = this->GetGUID(name.c_str());
|
||||
const char* name = di->c_str();
|
||||
std::string guid = this->GetGUID(name);
|
||||
if(guid.size() == 0)
|
||||
{
|
||||
std::string m = "Target: ";
|
||||
|
@ -235,10 +214,8 @@ cmGlobalVisualStudio71Generator
|
|||
m += name;
|
||||
cmSystemTools::Error(m.c_str());
|
||||
}
|
||||
|
||||
fout << "\t\t{" << guid << "} = {" << guid << "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -408,6 +408,18 @@ void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout,
|
|||
<< this->ConvertToSolutionPath(dir)
|
||||
<< "\\" << dspname << ext << "\", \"{"
|
||||
<< this->GetGUID(dspname) << "}\"\nEndProject\n";
|
||||
|
||||
UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
|
||||
if(ui != this->UtilityDepends.end())
|
||||
{
|
||||
const char* uname = ui->second.c_str();
|
||||
fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
|
||||
<< uname << "\", \""
|
||||
<< this->ConvertToSolutionPath(dir)
|
||||
<< "\\" << uname << ".vcproj" << "\", \"{"
|
||||
<< this->GetGUID(uname) << "}\"\n"
|
||||
<< "EndProject\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -422,59 +434,30 @@ cmGlobalVisualStudio7Generator
|
|||
const char*, cmTarget& target)
|
||||
{
|
||||
int depcount = 0;
|
||||
// insert Begin Project Dependency Project_Dep_Name project stuff here
|
||||
if (target.GetType() != cmTarget::STATIC_LIBRARY)
|
||||
std::string dspguid = this->GetGUID(dspname);
|
||||
VSDependSet const& depends = this->VSTargetDepends[&target];
|
||||
for(VSDependSet::const_iterator di = depends.begin();
|
||||
di != depends.end(); ++di)
|
||||
{
|
||||
cmTarget::LinkLibraryVectorType::const_iterator j, jend;
|
||||
j = target.GetLinkLibraries().begin();
|
||||
jend = target.GetLinkLibraries().end();
|
||||
for(;j!= jend; ++j)
|
||||
{
|
||||
if(j->first != dspname)
|
||||
{
|
||||
// is the library part of this SLN ? If so add dependency
|
||||
if(this->FindTarget(0, j->first.c_str()))
|
||||
{
|
||||
std::string guid = this->GetGUID(j->first.c_str());
|
||||
const char* name = di->c_str();
|
||||
std::string guid = this->GetGUID(name);
|
||||
if(guid.size() == 0)
|
||||
{
|
||||
std::string m = "Target: ";
|
||||
m += dspname;
|
||||
m += target.GetName();
|
||||
m += " depends on unknown target: ";
|
||||
m += j->first.c_str();
|
||||
m += name;
|
||||
cmSystemTools::Error(m.c_str());
|
||||
}
|
||||
fout << "\t\t{" << this->GetGUID(dspname) << "}."
|
||||
<< depcount << " = {" << guid << "}\n";
|
||||
fout << "\t\t{" << dspguid << "}." << depcount << " = {" << guid << "}\n";
|
||||
depcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<cmStdString>::const_iterator i, end;
|
||||
// write utility dependencies.
|
||||
i = target.GetUtilities().begin();
|
||||
end = target.GetUtilities().end();
|
||||
for(;i!= end; ++i)
|
||||
UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
|
||||
if(ui != this->UtilityDepends.end())
|
||||
{
|
||||
if(*i != dspname)
|
||||
{
|
||||
std::string name = this->GetUtilityForTarget(target, i->c_str());
|
||||
std::string guid = this->GetGUID(name.c_str());
|
||||
if(guid.size() == 0)
|
||||
{
|
||||
std::string m = "Target: ";
|
||||
m += dspname;
|
||||
m += " depends on unknown target: ";
|
||||
m += name.c_str();
|
||||
cmSystemTools::Error(m.c_str());
|
||||
}
|
||||
|
||||
fout << "\t\t{" << this->GetGUID(dspname) << "}." << depcount << " = {"
|
||||
<< guid << "}\n";
|
||||
depcount++;
|
||||
}
|
||||
const char* uname = ui->second.c_str();
|
||||
fout << "\t\t{" << this->GetGUID(uname) << "}.0 = {" << dspguid << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,6 +520,61 @@ void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout)
|
|||
fout << "Microsoft Visual Studio Solution File, Format Version 7.00\n";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget* target)
|
||||
{
|
||||
std::string pname = target->GetName();
|
||||
pname += "_UTILITY";
|
||||
std::string fname = target->GetMakefile()->GetStartOutputDirectory();
|
||||
fname += "/";
|
||||
fname += pname;
|
||||
fname += ".vcproj";
|
||||
cmGeneratedFileStream fout(fname.c_str());
|
||||
fout.SetCopyIfDifferent(true);
|
||||
this->CreateGUID(pname.c_str());
|
||||
std::string guid = this->GetGUID(pname.c_str());
|
||||
|
||||
fout <<
|
||||
"<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
|
||||
"<VisualStudioProject\n"
|
||||
"\tProjectType=\"Visual C++\"\n"
|
||||
"\tVersion=\"" << this->GetIDEVersion() << "0\"\n"
|
||||
"\tName=\"" << pname << "\"\n"
|
||||
"\tProjectGUID=\"{" << guid << "}\"\n"
|
||||
"\tKeyword=\"Win32Proj\">\n"
|
||||
"\t<Platforms><Platform Name=\"Win32\"/></Platforms>\n"
|
||||
"\t<Configurations>\n"
|
||||
;
|
||||
for(std::vector<std::string>::iterator i = this->Configurations.begin();
|
||||
i != this->Configurations.end(); ++i)
|
||||
{
|
||||
fout <<
|
||||
"\t\t<Configuration\n"
|
||||
"\t\t\tName=\"" << *i << "|Win32\"\n"
|
||||
"\t\t\tOutputDirectory=\"" << *i << "\"\n"
|
||||
"\t\t\tIntermediateDirectory=\"" << pname << ".dir\\" << *i << "\"\n"
|
||||
"\t\t\tConfigurationType=\"10\"\n"
|
||||
"\t\t\tUseOfMFC=\"0\"\n"
|
||||
"\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"
|
||||
"\t\t\tCharacterSet=\"2\">\n"
|
||||
"\t\t</Configuration>\n"
|
||||
;
|
||||
}
|
||||
fout <<
|
||||
"\t</Configurations>\n"
|
||||
"\t<Files></Files>\n"
|
||||
"\t<Globals></Globals>\n"
|
||||
"</VisualStudioProject>\n"
|
||||
;
|
||||
|
||||
if(fout.Close())
|
||||
{
|
||||
this->FileReplacedDuringGenerate(fname);
|
||||
}
|
||||
return pname;
|
||||
}
|
||||
|
||||
std::string cmGlobalVisualStudio7Generator::GetGUID(const char* name)
|
||||
{
|
||||
std::string guidStoreName = name;
|
||||
|
|
|
@ -113,6 +113,7 @@ protected:
|
|||
bool partOfDefaultBuild);
|
||||
virtual void WriteSLNFooter(std::ostream& fout);
|
||||
virtual void WriteSLNHeader(std::ostream& fout);
|
||||
virtual std::string WriteUtilityDepend(cmTarget* target);
|
||||
virtual void AddPlatformDefinitions(cmMakefile* mf);
|
||||
|
||||
virtual void WriteTargetsToSolution(
|
||||
|
|
|
@ -74,9 +74,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();
|
||||
|
@ -225,129 +222,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());
|
||||
vsTargetDepend.insert(j->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Look at each utility dependency.
|
||||
for(std::set<cmStdString>::const_iterator ui =
|
||||
target.GetUtilities().begin();
|
||||
ui != target.GetUtilities().end(); ++ui)
|
||||
std::set<cmStdString> const& utils = target.GetUtilities();
|
||||
for(std::set<cmStdString>::const_iterator i = utils.begin();
|
||||
i != utils.end(); ++i)
|
||||
{
|
||||
if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
|
||||
if(*i != target.GetName())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
// 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()))
|
||||
{
|
||||
alt->AddUtility(target.GetName());
|
||||
std::string name = this->GetUtilityForTarget(target, i->c_str());
|
||||
vsTargetDepend.insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,10 +302,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 ||
|
||||
|
@ -386,19 +331,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -408,30 +353,6 @@ cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
|
|||
return name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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>
|
||||
|
||||
|
|
|
@ -61,7 +61,6 @@ public:
|
|||
|
||||
// return true if target is fortran only
|
||||
bool TargetIsFortranOnly(cmTarget& t);
|
||||
const char* GetUtilityForTarget(cmTarget& target, const char*);
|
||||
|
||||
/** Get the top-level registry key for this VS version. */
|
||||
std::string GetRegistryBase();
|
||||
|
@ -71,8 +70,6 @@ public:
|
|||
virtual bool IsMultiConfig() { return true; }
|
||||
|
||||
protected:
|
||||
void FixUtilityDepends();
|
||||
|
||||
// Does this VS version link targets to each other if there are
|
||||
// dependencies in the SLN file? This was done for VS versions
|
||||
// below 8.
|
||||
|
@ -90,14 +87,18 @@ protected:
|
|||
OrderedTargetDependSet(cmGlobalGenerator::TargetDependSet const&);
|
||||
};
|
||||
|
||||
virtual void GetTargetSets(TargetDependSet& projectTargets,
|
||||
TargetDependSet& originalTargets,
|
||||
cmLocalGenerator* root, GeneratorVector const&);
|
||||
virtual bool ComputeTargetDepends();
|
||||
class VSDependSet: public std::set<cmStdString> {};
|
||||
class VSDependMap: public std::map<cmTarget*, VSDependSet> {};
|
||||
VSDependMap VSTargetDepends;
|
||||
void ComputeVSTargetDepends(cmTarget&);
|
||||
|
||||
bool CheckTargetLinks(cmTarget& target, const char* name);
|
||||
private:
|
||||
void FixUtilityDependsForTarget(cmTarget& target);
|
||||
void CreateUtilityDependTarget(cmTarget& target);
|
||||
std::string GetUtilityForTarget(cmTarget& target, const char*);
|
||||
virtual std::string WriteUtilityDepend(cmTarget*) = 0;
|
||||
std::string GetUtilityDepend(cmTarget* target);
|
||||
typedef std::map<cmTarget*, cmStdString> UtilityDependsMap;
|
||||
UtilityDependsMap UtilityDepends;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue