summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmGlobalGenerator.cxx62
-rw-r--r--Source/cmGlobalGenerator.h14
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx4
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx231
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx511
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h24
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx18
-rw-r--r--Source/cmLocalVisualStudio7Generator.h2
-rw-r--r--Tests/CMakeLists.txt36
-rw-r--r--Tests/SubProject/CMakeLists.txt5
-rw-r--r--Tests/SubProject/bar.cxx4
-rw-r--r--Tests/SubProject/car.cxx6
13 files changed, 394 insertions, 526 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index dfa6e05..a287ad6 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -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;
}
+
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 4654a41..b40b5d8 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -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);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index ff29c4a..746ddfa 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -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)
{
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 48efee1..26a095e 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -45,228 +45,34 @@ void cmGlobalVisualStudio71Generator::AddPlatformDefinitions(cmMakefile* mf)
mf->AddDefinition("MSVC71", "1");
}
-// Write a SLN file to the stream
+
void cmGlobalVisualStudio71Generator
::WriteSLNFile(std::ostream& fout,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
-{
+{
// 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) << "\", \"{"
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index c8a2385..f357c8f 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -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);
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index f3dcc60..0a084ee 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -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)
+ if(std::find(this->Configurations.begin(),
+ this->Configurations.end(),
+ *i) == this->Configurations.end())
{
- len = endpos - start;
+ this->Configurations.push_back(*i);
}
- 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())
- {
- this->Configurations.push_back(config);
- }
- }
- 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,190 +240,219 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile()
}
-// Write a SLN file to the stream
-void cmGlobalVisualStudio7Generator
-::WriteSLNFile(std::ostream& fout,
- cmLocalGenerator* root,
- std::vector<cmLocalGenerator*>& generators)
+void cmGlobalVisualStudio7Generator::AddAllBuildDepends(
+ cmLocalGenerator* root,
+ cmTarget* target,
+ cmGlobalGenerator::TargetDependSet& originalTargets)
{
- // Write out the header for a SLN file
- this->WriteSLNHeader(fout);
-
- // Get the start directory with the trailing slash
+ // if this is the special ALL_BUILD utility, then
+ // make it depend on every other non UTILITY project.
+ for(cmGlobalGenerator::TargetDependSet::iterator ot =
+ originalTargets.begin(); ot != originalTargets.end(); ++ot)
+ {
+ cmTarget* t = const_cast<cmTarget*>(*ot);
+ if(!this->IsExcluded(root, *t))
+ {
+ if (t->GetType() == cmTarget::UTILITY ||
+ t->GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ target->AddUtility(t->GetName());
+ }
+ else
+ {
+ target->AddLinkLibrary(t->GetName(),cmTarget::GENERAL);
+ }
+ }
+ }
+}
+
+void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
+ std::ostream& fout,
+ cmLocalGenerator* root,
+ cmGlobalGenerator::TargetDependSet& projectTargets)
+{
+ // 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 += "/";
- 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]))
+ 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)
{
- continue;
+ 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());
}
- 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)
+ else
{
- // special handling for the current makefile
- if(mf == generators[0]->GetMakefile())
+ // if the target is an onlyOnceNames do it once
+ std::map<cmStdString, int>::iterator o =
+ onlyOnceMap.find(target->GetName());
+ bool skip = false;
+ if(o != onlyOnceMap.end())
{
- 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)
+ if(o->second > 0)
{
- 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);
- }
- }
- }
- }
+ skip = true;
+ }
+ else
+ {
+ o->second++;
}
}
- // 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());
+ // if not skipping the project then write it into the
+ // solution
+ if(!skip)
+ {
+ const char *vcprojName =
+ target->GetProperty("GENERATOR_FILE_NAME");
+ if(vcprojName)
+ {
+ 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);
+ }
}
- else
+ }
+ }
+}
+
+
+void cmGlobalVisualStudio7Generator::WriteTargetDepends(
+ std::ostream& fout,
+ cmGlobalGenerator::TargetDependSet& projectTargets
+ )
+{
+ for(cmGlobalGenerator::TargetDependSet::iterator tt =
+ projectTargets.begin(); tt != projectTargets.end(); ++tt)
+ {
+ cmTarget* target = const_cast<cmTarget*>(*tt);
+ cmMakefile* mf = target->GetMakefile();
+ if (strncmp(target->GetName(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
+ {
+ cmCustomCommand cc = target->GetPostBuildCommands()[0];
+ const cmCustomCommandLines& cmds = cc.GetCommandLines();
+ std::string name = cmds[0][0];
+ std::vector<std::string> depends = cc.GetDepends();
+ std::vector<std::string>::iterator iter;
+ int depcount = 0;
+ for(iter = depends.begin(); iter != depends.end(); ++iter)
{
- bool skip = false;
- if(l->first == "ALL_BUILD" )
- {
- if(doneAllBuild)
- {
- 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;
- }
- }
- if(!skip)
- {
- const char *dspname =
- l->second.GetProperty("GENERATOR_FILE_NAME");
- if (dspname)
- {
- this->WriteProject(fout, dspname, dir.c_str(),l->second);
- }
- }
+ std::string guid = this->GetGUID(iter->c_str());
+ if(guid.size() == 0)
+ {
+ std::string m = "Target: ";
+ m += target->GetName();
+ m += " depends on unknown target: ";
+ m += iter->c_str();
+ cmSystemTools::Error(m.c_str());
+ }
+
+ fout << "\t\t{" << this->GetGUID(name.c_str())
+ << "}." << depcount << " = {" << guid.c_str() << "}\n";
+ depcount++;
+ }
+ }
+ else
+ {
+ const char *vcprojName =
+ target->GetProperty("GENERATOR_FILE_NAME");
+ if (vcprojName)
+ {
+ 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";
@@ -459,99 +463,15 @@ void cmGlobalVisualStudio7Generator
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)
- {
- 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];
- std::vector<std::string> depends = cc.GetDepends();
- std::vector<std::string>::iterator iter;
- int depcount = 0;
- for(iter = depends.begin(); iter != depends.end(); ++iter)
- {
- std::string guid = this->GetGUID(iter->c_str());
- if(guid.size() == 0)
- {
- std::string m = "Target: ";
- m += l->first;
- m += " depends on unknown target: ";
- m += iter->c_str();
- cmSystemTools::Error(m.c_str());
- }
-
- fout << "\t\t{" << this->GetGUID(name.c_str())
- << "}." << depcount << " = {" << guid.c_str() << "}\n";
- depcount++;
- }
- }
- else
- {
- const char *dspname =
- l->second.GetProperty("GENERATOR_FILE_NAME");
- if (dspname)
- {
- this->WriteProjectDepends(fout, dspname,
- dir.c_str(), l->second);
- }
- }
- }
- }
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 << "\", \""
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index e90b4db..7b723f2 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -114,11 +114,29 @@ 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,
- const std::vector<std::string>& dependencies);
+ virtual void WriteExternalProject(std::ostream& fout,
+ const char* name,
+ const char* path,
+ const std::vector<std::string>& dependencies);
std::string ConvertToSolutionPath(const char* path);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 18b5721..a22f509 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -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()
{
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 11b6736..b599362 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -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);
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 09c62e1..8314fbd 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -52,7 +52,40 @@ IF(BUILD_TESTING)
ADD_TEST_MACRO(SourceGroups SourceGroups)
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"
diff --git a/Tests/SubProject/CMakeLists.txt b/Tests/SubProject/CMakeLists.txt
new file mode 100644
index 0000000..f825749
--- /dev/null
+++ b/Tests/SubProject/CMakeLists.txt
@@ -0,0 +1,5 @@
+project(SubProject)
+message("${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+add_library(bar bar.cxx)
+add_executable(car car.cxx)
+add_subdirectory(foo)
diff --git a/Tests/SubProject/bar.cxx b/Tests/SubProject/bar.cxx
new file mode 100644
index 0000000..c3f6a18
--- /dev/null
+++ b/Tests/SubProject/bar.cxx
@@ -0,0 +1,4 @@
+int bar()
+{
+ return 10;
+}
diff --git a/Tests/SubProject/car.cxx b/Tests/SubProject/car.cxx
new file mode 100644
index 0000000..95de4a3
--- /dev/null
+++ b/Tests/SubProject/car.cxx
@@ -0,0 +1,6 @@
+int main(int ac, char** av)
+{
+ (void) ac;
+ (void) av;
+ return 0;
+}