ENH: fix for bug 3218 dependant projects are written out automatically if they are in the project. Also fix bug 5829, remove hard coded CMAKE_CONFIGURATION_TYPES from vs 7 generator

This commit is contained in:
Bill Hoffman 2008-01-30 12:04:38 -05:00
parent 21e6791789
commit 8a83f09637
13 changed files with 400 additions and 532 deletions

View File

@ -1036,7 +1036,6 @@ int cmGlobalGenerator::Build(
std::string makeCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName,
0, target, config, false, fast);
if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), output,
&retVal, 0, false, timeout))
{
@ -1291,7 +1290,7 @@ void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
// Add dependencies of the included target. An excluded
// target may still be included if it is a dependency of a
// non-excluded target.
TargetDependSet const& tgtdeps = this->GetTargetDepends(target);
TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator ti = tgtdeps.begin();
ti != tgtdeps.end(); ++ti)
{
@ -1684,7 +1683,7 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
//----------------------------------------------------------------------------
cmGlobalGenerator::TargetDependSet const&
cmGlobalGenerator::GetTargetDepends(cmTarget const& target)
cmGlobalGenerator::GetTargetDirectDepends(cmTarget const& target)
{
// Clarify the role of the input target.
cmTarget const* depender = ⌖
@ -1863,6 +1862,62 @@ cmGlobalGenerator
std::back_inserter(filenames));
}
void
cmGlobalGenerator
::GetTargetSets(cmGlobalGenerator::TargetDependSet& projectTargets,
cmGlobalGenerator::TargetDependSet& originalTargets,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*> const& generators)
{
// loop over all local generators
for(std::vector<cmLocalGenerator*>::const_iterator i = generators.begin();
i != generators.end(); ++i)
{
// check to make sure generator is not excluded
if(this->IsExcluded(root, *i))
{
continue;
}
cmMakefile* mf = (*i)->GetMakefile();
// Get the targets in the makefile
cmTargets &tgts = mf->GetTargets();
// loop over all the targets
for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
{
cmTarget* target = &l->second;
// put the target in the set of original targets
originalTargets.insert(target);
// Get the set of targets that depend on target
this->AddTargetDepends(target,
projectTargets);
}
}
}
void
cmGlobalGenerator::AddTargetDepends(cmTarget* target,
cmGlobalGenerator::TargetDependSet&
projectTargets)
{
// add the target itself
projectTargets.insert(target);
// get the direct depends of target
cmGlobalGenerator::TargetDependSet const& tset
= this->GetTargetDirectDepends(*target);
if(tset.size())
{
// if there are targets that depend on target
// add them and their depends as well
for(cmGlobalGenerator::TargetDependSet::const_iterator i =
tset.begin(); i != tset.end(); ++i)
{
cmTarget* dtarget = const_cast<cmTarget*>(*i);
this->AddTargetDepends(dtarget, projectTargets);
}
}
}
//----------------------------------------------------------------------------
void cmGlobalGenerator::AddToManifest(const char* config,
std::string const& f)
@ -1901,3 +1956,4 @@ cmGlobalGenerator::GetDirectoryContent(std::string const& dir, bool needDisk)
}
return dc;
}

View File

@ -234,8 +234,9 @@ public:
// Class to track a set of dependencies.
class TargetDependSet: public std::set<cmTarget const*> {};
// what targets does the specified target depend on
TargetDependSet const& GetTargetDepends(cmTarget const& target);
// what targets does the specified target depend on directly
// via a target_link_libraries or add_dependencies
TargetDependSet const& GetTargetDirectDepends(cmTarget const& target);
const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap()
const {return this->ProjectMap;}
@ -245,6 +246,15 @@ public:
void GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames);
protected:
// for a project collect all its targets by following depend
// information, and also collect all the targets
void GetTargetSets(cmGlobalGenerator::TargetDependSet& projectTargets,
cmGlobalGenerator::TargetDependSet& originalTargets,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*> const& generators);
void AddTargetDepends(cmTarget* target,
cmGlobalGenerator::TargetDependSet&
projectTargets);
void SetLanguageEnabledFlag(const char* l, cmMakefile* mf);
void SetLanguageEnabledMaps(const char* l, cmMakefile* mf);

View File

@ -861,7 +861,7 @@ int cmGlobalUnixMakefileGenerator3
(target.GetMakefile()->GetLocalGenerator());
result = static_cast<int>(lg->ProgressFiles[target.GetName()].size());
TargetDependSet const& depends = this->GetTargetDepends(target);
TargetDependSet const& depends = this->GetTargetDirectDepends(target);
TargetDependSet::const_iterator i;
for (i = depends.begin(); i != depends.end(); ++i)
@ -898,7 +898,7 @@ cmGlobalUnixMakefileGenerator3
::AppendGlobalTargetDepends(std::vector<std::string>& depends,
cmTarget& target)
{
TargetDependSet const& depends_set = this->GetTargetDepends(target);
TargetDependSet const& depends_set = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator i = depends_set.begin();
i != depends_set.end(); ++i)
{

View File

@ -45,7 +45,7 @@ void cmGlobalVisualStudio71Generator::AddPlatformDefinitions(cmMakefile* mf)
mf->AddDefinition("MSVC71", "1");
}
// Write a SLN file to the stream
void cmGlobalVisualStudio71Generator
::WriteSLNFile(std::ostream& fout,
cmLocalGenerator* root,
@ -54,219 +54,25 @@ void cmGlobalVisualStudio71Generator
// Write out the header for a SLN file
this->WriteSLNHeader(fout);
// Get the start directory with the trailing slash
std::string rootdir = root->GetMakefile()->GetStartOutputDirectory();
rootdir += "/";
bool doneAllBuild = false;
bool doneCheckBuild = false;
bool doneRunTests = false;
bool doneInstall = false;
bool doneEditCache = false;
bool doneRebuildCache = false;
bool donePackage = false;
// For each cmMakefile, create a VCProj for it, and
// add it to this SLN file
unsigned int i;
for(i = 0; i < generators.size(); ++i)
{
if(this->IsExcluded(root, generators[i]))
{
continue;
}
cmMakefile* mf = generators[i]->GetMakefile();
// Get the source directory from the makefile
std::string dir = mf->GetStartOutputDirectory();
// remove the home directory and / from the source directory
// this gives a relative path
cmSystemTools::ReplaceString(dir, rootdir.c_str(), "");
// Get the list of create dsp files names from the cmVCProjWriter, more
// than one dsp could have been created per input CMakeLists.txt file
// for each target
cmTargets &tgts = generators[i]->GetMakefile()->GetTargets();
cmTargets::iterator l = tgts.begin();
for(; l != tgts.end(); ++l)
{
// special handling for the current makefile
if(mf == generators[0]->GetMakefile())
{
dir = "."; // no subdirectory for project generated
// if this is the special ALL_BUILD utility, then
// make it depend on every other non UTILITY project.
// This is done by adding the names to the GetUtilities
// vector on the makefile
if(l->first == "ALL_BUILD" && !doneAllBuild)
{
unsigned int j;
for(j = 0; j < generators.size(); ++j)
{
cmTargets &atgts = generators[j]->GetMakefile()->GetTargets();
for(cmTargets::iterator al = atgts.begin();
al != atgts.end(); ++al)
{
if (!al->second.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
if (al->second.GetType() == cmTarget::UTILITY ||
al->second.GetType() == cmTarget::GLOBAL_TARGET)
{
l->second.AddUtility(al->first.c_str());
}
else
{
l->second.AddLinkLibrary(al->first,cmTarget::GENERAL);
}
}
}
}
}
}
// Write the project into the SLN file
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{
cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project = cmds[0][0];
std::string location = cmds[0][1];
this->WriteExternalProject(fout, project.c_str(),
location.c_str(), cc.GetDepends());
}
else
{
bool skip = false;
if(l->first == "ALL_BUILD" )
{
if(doneAllBuild)
{
skip = true;
}
else
{
doneAllBuild = true;
}
}
if(l->first == CMAKE_CHECK_BUILD_SYSTEM_TARGET)
{
if(doneCheckBuild)
{
skip = true;
}
else
{
doneCheckBuild = true;
}
}
if(l->first == "INSTALL")
{
if(doneInstall)
{
skip = true;
}
else
{
doneInstall = true;
}
}
if(l->first == "RUN_TESTS")
{
if(doneRunTests)
{
skip = true;
}
else
{
doneRunTests = true;
}
}
if(l->first == "EDIT_CACHE")
{
if(doneEditCache)
{
skip = true;
}
else
{
doneEditCache = true;
}
}
if(l->first == "REBUILD_CACHE")
{
if(doneRebuildCache)
{
skip = true;
}
else
{
doneRebuildCache = true;
}
}
if(l->first == "PACKAGE")
{
if(donePackage)
{
skip = true;
}
else
{
donePackage = true;
}
}
if(!skip)
{
const char *dspname =
l->second.GetProperty("GENERATOR_FILE_NAME");
if (dspname)
{
this->WriteProject(fout, dspname, dir.c_str(),l->second);
}
}
}
}
}
// collect the set of targets for this project by
// tracing depends of all targets.
// also collect the set of targets that are explicitly
// in this project.
cmGlobalGenerator::TargetDependSet projectTargets;
cmGlobalGenerator::TargetDependSet originalTargets;
this->GetTargetSets(projectTargets,
originalTargets,
root, generators);
this->WriteTargetsToSolution(fout, root, projectTargets, originalTargets);
// Write out the configurations information for the solution
fout << "Global\n";
// Write out the configurations for the solution
this->WriteSolutionConfigurations(fout);
fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
<< ") = postSolution\n";
// loop over again and compute the depends
for(i = 0; i < generators.size(); ++i)
{
cmMakefile* mf = generators[i]->GetMakefile();
cmLocalVisualStudio7Generator* pg =
static_cast<cmLocalVisualStudio7Generator*>(generators[i]);
// Get the list of create dsp files names from the cmVCProjWriter, more
// than one dsp could have been created per input CMakeLists.txt file
// for each target
cmTargets &tgts = pg->GetMakefile()->GetTargets();
cmTargets::iterator l = tgts.begin();
std::string dir = mf->GetStartDirectory();
for(; l != tgts.end(); ++l)
{
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{
cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project = cmds[0][0];
this->WriteProjectConfigurations(fout, project.c_str(),
true);
}
else
{
bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
root->GetMakefile()->GetProjectName(),
&l->second);
const char *dspname =
l->second.GetProperty("GENERATOR_FILE_NAME");
if (dspname)
{
this->WriteProjectConfigurations(fout, dspname,
partOfDefaultBuild);
}
}
}
}
// Write out the configurations for all the targets in the project
this->WriteTargetConfigurations(fout, root, projectTargets);
fout << "\tEndGlobalSection\n";
// Write the footer for the SLN file
this->WriteSLNFooter(fout);
}
@ -338,7 +144,9 @@ cmGlobalVisualStudio71Generator
if(j->first != dspname)
{
// is the library part of this SLN ? If so add dependency
if(this->FindTarget(this->CurrentProject.c_str(), j->first.c_str()))
// 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";
@ -379,6 +187,7 @@ void cmGlobalVisualStudio71Generator
const char* location,
const std::vector<std::string>& depends)
{
std::cout << "WriteExternalProject vs71\n";
fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
<< name << "\", \""
<< this->ConvertToSolutionPath(location) << "\", \"{"

View File

@ -56,7 +56,8 @@ protected:
virtual void WriteProjectConfigurations(std::ostream& fout,
const char* name,
bool partOfDefaultBuild);
virtual void WriteExternalProject(std::ostream& fout, const char* name,
virtual void WriteExternalProject(std::ostream& fout,
const char* name,
const char* path,
const std::vector<std::string>& depends);
virtual void WriteSLNFooter(std::ostream& fout);

View File

@ -150,45 +150,20 @@ void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
= this->CMakeInstance->GetCacheDefinition("CMAKE_CONFIGURATION_TYPES");
if ( ct )
{
std::string configTypes = ct;
std::string::size_type start = 0;
std::string::size_type endpos = 0;
while(endpos != std::string::npos)
std::vector<std::string> argsOut;
cmSystemTools::ExpandListArgument(ct, argsOut);
for(std::vector<std::string>::iterator i = argsOut.begin();
i != argsOut.end(); ++i)
{
endpos = configTypes.find_first_of(" ;", start);
std::string config;
std::string::size_type len;
if(endpos != std::string::npos)
{
len = endpos - start;
}
else
{
len = configTypes.size() - start;
}
config = configTypes.substr(start, len);
if(config == "Debug" || config == "Release" ||
config == "MinSizeRel" || config == "RelWithDebInfo")
{
// only add unique configurations
if(std::find(this->Configurations.begin(),
this->Configurations.end(),
config) == this->Configurations.end())
*i) == this->Configurations.end())
{
this->Configurations.push_back(config);
this->Configurations.push_back(*i);
}
}
else
{
cmSystemTools::Error(
"Invalid configuration type in CMAKE_CONFIGURATION_TYPES: ",
config.c_str(),
" (Valid types are Debug,Release,MinSizeRel,RelWithDebInfo)");
}
start = endpos+1;
}
}
// default to at least Debug and Release
if(this->Configurations.size() == 0)
{
this->Configurations.push_back("Debug");
@ -265,220 +240,164 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile()
}
// Write a SLN file to the stream
void cmGlobalVisualStudio7Generator
::WriteSLNFile(std::ostream& fout,
void cmGlobalVisualStudio7Generator::AddAllBuildDepends(
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
cmTarget* target,
cmGlobalGenerator::TargetDependSet& originalTargets)
{
// Write out the header for a SLN file
this->WriteSLNHeader(fout);
// Get the start directory with the trailing slash
std::string rootdir = root->GetMakefile()->GetStartOutputDirectory();
rootdir += "/";
bool doneAllBuild = false;
bool doneRunTests = false;
bool doneInstall = false;
bool doneEditCache = false;
bool doneRebuildCache = false;
bool donePackage = false;
// 1.
// Collecte all targets in generators vector and the targets
// that they depend on
// 2. loop over all targets and put .vcproj reference
// into .sln file. .vcproj files should already exist
// from local generation step. Do not add "pulled" in .vcproj
// to ALL_BUILD.
// See: cmGlobalGenerator::GetTargetDepends
// cmGlobalGenerator::TargetDependSet myset;
// foreach t in all targets
// cmGlobalGenerator::TargetDependSet const& tset = GetTargetDepends(t);
// myset.insert(tset.begin(), tset.end());
// foreach t in myset
// t->GetMakefile()->GetLocalGenerator()->GetVCProjPath()
// if t was not in original set of targets disable all for it
// For each cmMakefile, create a VCProj for it, and
// add it to this SLN file
unsigned int i;
for(i = 0; i < generators.size(); ++i)
{
if(this->IsExcluded(root, generators[i]))
{
continue;
}
cmMakefile* mf = generators[i]->GetMakefile();
// Get the source directory from the makefile
std::string dir = mf->GetStartOutputDirectory();
// remove the home directory and / from the source directory
// this gives a relative path
cmSystemTools::ReplaceString(dir, rootdir.c_str(), "");
// Get the list of create dsp files names from the cmVCProjWriter, more
// than one dsp could have been created per input CMakeLists.txt file
// for each target
cmTargets &tgts = generators[i]->GetMakefile()->GetTargets();
for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
{
// special handling for the current makefile
if(mf == generators[0]->GetMakefile())
{
dir = "."; // no subdirectory for project generated
// if this is the special ALL_BUILD utility, then
// make it depend on every other non UTILITY project.
// This is done by adding the names to the GetUtilities
// vector on the makefile
if(l->first == "ALL_BUILD" && !doneAllBuild)
for(cmGlobalGenerator::TargetDependSet::iterator ot =
originalTargets.begin(); ot != originalTargets.end(); ++ot)
{
unsigned int j;
for(j = 0; j < generators.size(); ++j)
cmTarget* t = const_cast<cmTarget*>(*ot);
if(!this->IsExcluded(root, *t))
{
cmTargets &atgts = generators[j]->GetMakefile()->GetTargets();
for(cmTargets::iterator al = atgts.begin();
al != atgts.end(); ++al)
if (t->GetType() == cmTarget::UTILITY ||
t->GetType() == cmTarget::GLOBAL_TARGET)
{
if (!al->second.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
if (al->second.GetType() == cmTarget::UTILITY ||
al->second.GetType() == cmTarget::GLOBAL_TARGET)
{
l->second.AddUtility(al->first.c_str());
target->AddUtility(t->GetName());
}
else
{
l->second.AddLinkLibrary(al->first,cmTarget::GENERAL);
target->AddLinkLibrary(t->GetName(),cmTarget::GENERAL);
}
}
}
}
}
}
// Write the project into the SLN file
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
std::ostream& fout,
cmLocalGenerator* root,
cmGlobalGenerator::TargetDependSet& projectTargets)
{
cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
// loop over again and write out configurations for each target
// in the solution
for(cmGlobalGenerator::TargetDependSet::iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
cmTarget* target = const_cast<cmTarget*>(*tt);
if (strncmp(target->GetName(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{
cmCustomCommand cc = target->GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project = cmds[0][0];
this->WriteProjectConfigurations(fout, project.c_str(),
true);
}
else
{
bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
root->GetMakefile()->GetProjectName(), target);
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName)
{
this->WriteProjectConfigurations(fout, vcprojName,
partOfDefaultBuild);
}
}
}
}
void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
std::ostream& fout,
cmLocalGenerator* root,
cmGlobalGenerator::TargetDependSet& projectTargets,
cmGlobalGenerator::TargetDependSet& originalTargets
)
{
// Create a map of project that should only show up once
// in a project
const char* onlyOnceNames[] =
{"INCLUDE_EXTERNAL_MSPROJECT","CMAKE_CHECK_BUILD_SYSTEM_TARGET",
"INSTALL", "RUN_TESTS", "EDIT_CACHE", "REBUILD_CACHE", "PACKAGE", 0};
std::map<cmStdString, int> onlyOnceMap;
int i =0;
for(const char* name = onlyOnceNames[i];
name != 0; name = onlyOnceNames[++i])
{
onlyOnceMap[name] = 0;
}
// add the CMAKE_CHECK_BUILD_SYSTEM_TARGET
onlyOnceMap[CMAKE_CHECK_BUILD_SYSTEM_TARGET] = 0;
std::string rootdir = root->GetMakefile()->GetStartOutputDirectory();
rootdir += "/";
for(cmGlobalGenerator::TargetDependSet::iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
cmTarget* target = const_cast<cmTarget*>(*tt);
cmMakefile* mf = target->GetMakefile();
// look for the all_build rule and add depends to all
// of the original targets (none that were "pulled" into this project)
if(mf == root->GetMakefile() &&
strcmp(target->GetName(), "ALL_BUILD") == 0)
{
this->AddAllBuildDepends(root, target, originalTargets);
}
// handle external vc project files
if (strncmp(target->GetName(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{
cmCustomCommand cc = target->GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project = cmds[0][0];
std::string location = cmds[0][1];
std::cout << "About to call WriteExternalProject " << this->GetName() << "\n";
this->WriteExternalProject(fout, project.c_str(),
location.c_str(), cc.GetDepends());
}
else
{
// if the target is an onlyOnceNames do it once
std::map<cmStdString, int>::iterator o =
onlyOnceMap.find(target->GetName());
bool skip = false;
if(l->first == "ALL_BUILD" )
if(o != onlyOnceMap.end())
{
if(doneAllBuild)
if(o->second > 0)
{
skip = true;
}
else
{
doneAllBuild = true;
}
}
if(l->first == "INSTALL")
{
if(doneInstall)
{
skip = true;
}
else
{
doneInstall = true;
}
}
if(l->first == "RUN_TESTS")
{
if(doneRunTests)
{
skip = true;
}
else
{
doneRunTests = true;
}
}
if(l->first == "EDIT_CACHE")
{
if(doneEditCache)
{
skip = true;
}
else
{
doneEditCache = true;
}
}
if(l->first == "REBUILD_CACHE")
{
if(doneRebuildCache)
{
skip = true;
}
else
{
doneRebuildCache = true;
}
}
if(l->first == "PACKAGE")
{
if(donePackage)
{
skip = true;
}
else
{
donePackage = true;
o->second++;
}
}
// if not skipping the project then write it into the
// solution
if(!skip)
{
const char *dspname =
l->second.GetProperty("GENERATOR_FILE_NAME");
if (dspname)
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
if(vcprojName)
{
this->WriteProject(fout, dspname, dir.c_str(),l->second);
cmMakefile* tmf = target->GetMakefile();
std::string dir = tmf->GetStartOutputDirectory();
dir = root->Convert(dir.c_str(),
cmLocalGenerator::START_OUTPUT);
this->WriteProject(fout, vcprojName, dir.c_str(),
*target);
}
}
}
}
}
fout << "Global\n"
<< "\tGlobalSection(SolutionConfiguration) = preSolution\n";
int c = 0;
for(std::vector<std::string>::iterator i = this->Configurations.begin();
i != this->Configurations.end(); ++i)
{
fout << "\t\tConfigName." << c << " = " << *i << "\n";
c++;
}
fout << "\tEndGlobalSection\n"
<< "\tGlobalSection(ProjectDependencies) = postSolution\n";
// loop over again and compute the depends
for(i = 0; i < generators.size(); ++i)
void cmGlobalVisualStudio7Generator::WriteTargetDepends(
std::ostream& fout,
cmGlobalGenerator::TargetDependSet& projectTargets
)
{
cmMakefile* mf = generators[i]->GetMakefile();
cmLocalVisualStudio7Generator* pg =
static_cast<cmLocalVisualStudio7Generator*>(generators[i]);
// Get the list of create dsp files names from the cmVCProjWriter, more
// than one dsp could have been created per input CMakeLists.txt file
// for each target
cmTargets &tgts = pg->GetMakefile()->GetTargets();
cmTargets::iterator l = tgts.begin();
std::string dir = mf->GetStartDirectory();
for(; l != tgts.end(); ++l)
for(cmGlobalGenerator::TargetDependSet::iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
cmTarget* target = const_cast<cmTarget*>(*tt);
cmMakefile* mf = target->GetMakefile();
if (strncmp(target->GetName(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{
cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
cmCustomCommand cc = target->GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string name = cmds[0][0];
std::vector<std::string> depends = cc.GetDepends();
@ -490,7 +409,7 @@ void cmGlobalVisualStudio7Generator
if(guid.size() == 0)
{
std::string m = "Target: ";
m += l->first;
m += target->GetName();
m += " depends on unknown target: ";
m += iter->c_str();
cmSystemTools::Error(m.c_str());
@ -503,55 +422,56 @@ void cmGlobalVisualStudio7Generator
}
else
{
const char *dspname =
l->second.GetProperty("GENERATOR_FILE_NAME");
if (dspname)
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName)
{
this->WriteProjectDepends(fout, dspname,
dir.c_str(), l->second);
std::string dir = mf->GetStartDirectory();
this->WriteProjectDepends(fout, vcprojName,
dir.c_str(), *target);
}
}
}
}
// Write a SLN file to the stream
void cmGlobalVisualStudio7Generator
::WriteSLNFile(std::ostream& fout,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
// Write out the header for a SLN file
this->WriteSLNHeader(fout);
// collect the set of targets for this project by
// tracing depends of all targets.
// also collect the set of targets that are explicitly
// in this project.
cmGlobalGenerator::TargetDependSet projectTargets;
cmGlobalGenerator::TargetDependSet originalTargets;
this->GetTargetSets(projectTargets,
originalTargets,
root, generators);
this->WriteTargetsToSolution(fout, root, projectTargets, originalTargets);
// Write out the configurations information for the solution
fout << "Global\n"
<< "\tGlobalSection(SolutionConfiguration) = preSolution\n";
int c = 0;
for(std::vector<std::string>::iterator i = this->Configurations.begin();
i != this->Configurations.end(); ++i)
{
fout << "\t\tConfigName." << c << " = " << *i << "\n";
c++;
}
fout << "\tEndGlobalSection\n";
// Write out project(target) depends
fout << "\tGlobalSection(ProjectDependencies) = postSolution\n";
this->WriteTargetDepends(fout, projectTargets);
fout << "\tEndGlobalSection\n";
// Write out the configurations for all the targets in the project
fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
// loop over again and compute the depends
for(i = 0; i < generators.size(); ++i)
{
cmMakefile* mf = generators[i]->GetMakefile();
cmLocalVisualStudio7Generator* pg =
static_cast<cmLocalVisualStudio7Generator*>(generators[i]);
// Get the list of create dsp files names from the cmVCProjWriter, more
// than one dsp could have been created per input CMakeLists.txt file
// for each target
cmTargets &tgts = pg->GetMakefile()->GetTargets();
cmTargets::iterator l = tgts.begin();
std::string dir = mf->GetStartDirectory();
for(; l != tgts.end(); ++l)
{
if(strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{
cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string name = cmds[0][0];
this->WriteProjectConfigurations(fout, name.c_str(),
true);
}
else
{
bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
root->GetMakefile()->GetProjectName(),
&l->second);
const char *dspname =
l->second.GetProperty("GENERATOR_FILE_NAME");
if (dspname)
{
this->WriteProjectConfigurations(fout, dspname,
partOfDefaultBuild);
}
}
}
}
this->WriteTargetConfigurations(fout, root, projectTargets);
fout << "\tEndGlobalSection\n";
// Write the footer for the SLN file
@ -611,7 +531,7 @@ cmGlobalVisualStudio7Generator
if(j->first != dspname)
{
// is the library part of this SLN ? If so add dependency
if(this->FindTarget(this->CurrentProject.c_str(), j->first.c_str()))
if(this->FindTarget(0, j->first.c_str()))
{
std::string guid = this->GetGUID(j->first.c_str());
if(guid.size() == 0)
@ -687,6 +607,7 @@ void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout,
const char* location,
const std::vector<std::string>&)
{
std::cout << "WriteExternalProject vs7\n";
std::string d = cmSystemTools::ConvertToOutputPath(location);
fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
<< name << "\", \""

View File

@ -114,10 +114,28 @@ protected:
virtual void WriteSLNHeader(std::ostream& fout);
virtual void AddPlatformDefinitions(cmMakefile* mf);
virtual void WriteTargetsToSolution(
std::ostream& fout,
cmLocalGenerator* root,
cmGlobalGenerator::TargetDependSet& projectTargets,
cmGlobalGenerator::TargetDependSet& originalTargets);
virtual void WriteTargetDepends(
std::ostream& fout,
cmGlobalGenerator::TargetDependSet& projectTargets);
virtual void WriteTargetConfigurations(
std::ostream& fout,
cmLocalGenerator* root,
cmGlobalGenerator::TargetDependSet& projectTargets);
void AddAllBuildDepends(cmLocalGenerator* root,
cmTarget* target,
cmGlobalGenerator::TargetDependSet& targets);
void GenerateConfigurations(cmMakefile* mf);
void WriteExternalProject(std::ostream& fout,
const char* name, const char* path,
virtual void WriteExternalProject(std::ostream& fout,
const char* name,
const char* path,
const std::vector<std::string>& dependencies);
std::string ConvertToSolutionPath(const char* path);

View File

@ -419,6 +419,7 @@ public:
// Check for specific options.
bool UsingUnicode();
bool IsDebug();
// Write options to output.
void OutputPreprocessorDefinitions(std::ostream& fout,
const char* prefix,
@ -667,7 +668,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
}
this->OutputTargetRules(fout, configName, target, libName);
this->OutputBuildTool(fout, configName, target);
this->OutputBuildTool(fout, configName, target, targetOptions.IsDebug());
fout << "\t\t</Configuration>\n";
}
@ -689,7 +690,8 @@ cmLocalVisualStudio7Generator
void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
const char* configName,
cmTarget &target)
cmTarget &target,
bool isDebug)
{
std::string temp;
std::string extraLinkOptions;
@ -802,8 +804,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
temp += targetNamePDB;
fout << "\t\t\t\tProgramDataBaseFile=\"" <<
this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
if(strcmp(configName, "Debug") == 0
|| strcmp(configName, "RelWithDebInfo") == 0)
if(isDebug)
{
fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
}
@ -869,8 +870,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tProgramDataBaseFile=\""
<< target.GetDirectory(configName) << "/" << targetNamePDB
<< "\"\n";
if(strcmp(configName, "Debug") == 0
|| strcmp(configName, "RelWithDebInfo") == 0)
if(isDebug)
{
fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
}
@ -1813,6 +1813,12 @@ void cmLocalVisualStudio7GeneratorOptions::AddFlag(const char* flag,
this->FlagMap[flag] = value;
}
bool cmLocalVisualStudio7GeneratorOptions::IsDebug()
{
return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
}
//----------------------------------------------------------------------------
bool cmLocalVisualStudio7GeneratorOptions::UsingUnicode()
{

View File

@ -96,7 +96,7 @@ private:
void OutputTargetRules(std::ostream& fout, const char* configName,
cmTarget &target, const char *libName);
void OutputBuildTool(std::ostream& fout, const char* configName,
cmTarget& t);
cmTarget& t, bool debug);
void OutputLibraryDirectories(std::ostream& fout,
std::vector<std::string> const& dirs);
void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target);

View File

@ -53,6 +53,39 @@ IF(BUILD_TESTING)
ADD_TEST_MACRO(Preprocess Preprocess)
ADD_TEST_MACRO(ExportImport ExportImport)
# test for correct sub-project generation
# not implemented in VS6 or Xcode
IF(NOT MSVC60 AND NOT XCODE)
# run cmake and configure all of SubProject
# but only build the independent executable car
ADD_TEST(SubProject ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/SubProject"
"${CMake_BINARY_DIR}/Tests/SubProject"
--build-project SubProject
--build-generator ${CMAKE_TEST_GENERATOR}
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
--build-target car
--test-command car
)
# For stage 2, do not run cmake again.
# Then build the foo sub project which should build
# the bar library which should be referenced because
# foo links to the static library bar, but bar is not
# directly in the foo sub project
ADD_TEST(SubProject-Stage2 ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/SubProject/foo"
"${CMake_BINARY_DIR}/Tests/SubProject/foo"
--build-generator ${CMAKE_TEST_GENERATOR}
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
--build-nocmake
--build-project foo
--build-target foo
--test-command foo
)
ENDIF(NOT MSVC60 AND NOT XCODE)
IF (CMAKE_STRICT)
ADD_TEST_MACRO(DocTest DocTest)
ENDIF (CMAKE_STRICT)
@ -505,7 +538,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=CVS -P ${CMake_SOURCE_DIR}/Utilities/Rel
ENDIF(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES syllable)
ADD_TEST(linkorder1 ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/LinkLineOrder"

View File

@ -0,0 +1,5 @@
project(SubProject)
message("${CMAKE_IMPORT_LIBRARY_SUFFIX}")
add_library(bar bar.cxx)
add_executable(car car.cxx)
add_subdirectory(foo)

4
Tests/SubProject/bar.cxx Normal file
View File

@ -0,0 +1,4 @@
int bar()
{
return 10;
}

6
Tests/SubProject/car.cxx Normal file
View File

@ -0,0 +1,6 @@
int main(int ac, char** av)
{
(void) ac;
(void) av;
return 0;
}