Attached Files | nested_projects.diff [^] (17,648 bytes) 2009-03-13 17:47 [Show Content] [Hide Content]diff -w -u cmake-2.6.3/Source/cmGlobalVisualStudio71Generator.cxx trunk/Source/cmGlobalVisualStudio71Generator.cxx
--- cmake-2.6.3/Source/cmGlobalVisualStudio71Generator.cxx 2009-02-21 14:17:00.000000000 -0800
+++ trunk/Source/cmGlobalVisualStudio71Generator.cxx 2009-03-13 14:12:34.131992800 -0700
@@ -119,6 +119,9 @@
this->WriteTargetsToSolution(fout, root, orderedProjectTargets,
originalTargets);
// Write out the configurations information for the solution
+
+ WriteAdditionalProjectSections(fout, root, generators);
+
fout << "Global\n";
// Write out the configurations for the solution
this->WriteSolutionConfigurations(fout);
@@ -127,6 +130,8 @@
// Write out the configurations for all the targets in the project
this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
fout << "\tEndGlobalSection\n";
+ WriteAdditionalGlobalSections(fout, root, generators);
+
// Write the footer for the SLN file
this->WriteSLNFooter(fout);
}
diff -w -u cmake-2.6.3/Source/cmGlobalVisualStudio71Generator.h trunk/Source/cmGlobalVisualStudio71Generator.h
--- cmake-2.6.3/Source/cmGlobalVisualStudio71Generator.h 2009-02-21 14:17:00.000000000 -0800
+++ trunk/Source/cmGlobalVisualStudio71Generator.h 2008-09-25 16:13:51.838500000 -0700
@@ -76,6 +76,12 @@
virtual void WriteSLNFooter(std::ostream& fout);
virtual void WriteSLNHeader(std::ostream& fout);
+ virtual void WriteAdditionalGlobalSections(std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators) {}
+
+ virtual void WriteAdditionalProjectSections(std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators) {}
+
std::string ProjectConfigurationSectionName;
};
#endif
diff -w -u cmake-2.6.3/Source/cmGlobalVisualStudio8Generator.cxx trunk/Source/cmGlobalVisualStudio8Generator.cxx
--- cmake-2.6.3/Source/cmGlobalVisualStudio8Generator.cxx 2009-02-21 14:17:00.000000000 -0800
+++ trunk/Source/cmGlobalVisualStudio8Generator.cxx 2008-09-25 16:13:47.088530400 -0700
@@ -247,10 +247,265 @@
}
//----------------------------------------------------------------------------
+ std::vector<std::string> buildPathAndSubPathVector(const std::string& path)
+ {
+ std::vector<std::string> ret;
+ ret.push_back(path);
+
+ int slashPos;
+ std::string workingPath = path;
+ while ((slashPos = workingPath.find_last_of("/")) != std::string::npos)
+ {
+ workingPath = workingPath.substr(0, slashPos);
+ ret.push_back(workingPath);
+ }
+
+ return ret;
+ }
+
+ //----------------------------------------------------------------------------
+ std::string lastPathComponent(const std::string& path)
+ {
+ int slashPos = path.find_last_of("/");
+ if (slashPos != std::string::npos)
+ {
+ return path.substr(slashPos+1, path.length() - slashPos);
+ }
+ return path;
+ }
+
+ //----------------------------------------------------------------------------
+ std::string allButLastPathComponent(const std::string& path)
+ {
+ int slashPos = path.find_last_of("/");
+ if (slashPos != std::string::npos)
+ {
+ return path.substr(0, slashPos);
+ }
+ return path;
+ }
+
+ //----------------------------------------------------------------------------
+ void cmGlobalVisualStudio8Generator::WriteAdditionalProjectSections(
+ std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+{
+ std::map<std::string, std::string> dspPathMap;
+ bool nestSolutionFolders = cmSystemTools::IsOn(root->GetMakefile()->GetDefinition("NEST_SOLUTION_FOLDERS"));
+
+ // Get the start directory with the trailing slash
+ std::string rootdir = root->GetMakefile()->GetStartOutputDirectory();
+ rootdir += "/";
+
+ // 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
+ std::vector<std::string> dspnames =
+ static_cast<cmLocalVisualStudio7Generator *>(generators[i])
+ ->GetCreatedProjectNames();
+ cmTargets &tgts = generators[i]->GetMakefile()->GetTargets();
+ cmTargets::iterator l = tgts.begin();
+ for( std::vector<std::string>::iterator si = dspnames.begin();
+ l != tgts.end() && si != dspnames.end();
+ ++l )
+ {
+ // special handling for the current makefile
+ if(mf == generators[0]->GetMakefile())
+ {
+ dir = "."; // no subdirectory for project generated
+ }
+ // Write the project into the SLN file
+ if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0){
+ } else if ((l->second.GetType() != cmTarget::INSTALL_FILES) &&
+ (l->second.GetType() != cmTarget::INSTALL_PROGRAMS))
+ {
+ if (si->c_str() != "")
+ {
+ if (l->first != "ALL_BUILD" && l->first != "INSTALL" && l->first != "RUN_TESTS" &&
+ l->first != "EDIT_CACHE" && l->first != "REBUILD_CACHE" && l->first != "PACKAGE" &&
+ l->first != "ZERO_CHECK" && l->first != "Continuous" && l->first != "Experimental" &&
+ l->first != "Nightly" && l->first != "NightlyMemoryCheck")
+ {
+ std::string path = generators[0]->Convert(mf->GetStartDirectory(), cmLocalGenerator::START);
+ dspPathMap.insert(std::make_pair(si->c_str(), path));
+ }
+ }
+ ++si;
+ }
+ }
+ }
+
+ // Construct the unique list of projects and guids to be written
+ std::map<std::string, std::string> pathGuidMap;
+ std::map<std::string, UINT > pathCountMap;
+ //std::vector<std::pair<std::string, std::string> > nestedProjects;
+
+ if (nestSolutionFolders)
+ {
+ std::map<std::string, std::string>::iterator dspPathIter, pathGuidIter;
+ for (dspPathIter = dspPathMap.begin(); dspPathIter != dspPathMap.end(); ++dspPathIter)
+ {
+ // Construct a vector of the path and all subpaths
+ std::vector<std::string> pathAndSubPaths = buildPathAndSubPathVector(dspPathIter->second);
+ std::string lastPartOfPath = lastPathComponent(dspPathIter->second);
+
+ // For each path, create a guid and insert it into pathGuidMap if it is unique
+ std::vector<std::string>::iterator pathIt;
+ for (pathIt = pathAndSubPaths.begin(); pathIt != pathAndSubPaths.end(); ++pathIt)
+ {
+ pathGuidIter = pathGuidMap.find(*pathIt);
+ if (pathGuidIter == pathGuidMap.end()) {
+ std::string path_entry = std::string("SOLUTION FOLDER: ") + *pathIt;
+ // Insert it
+ CreateGUID(path_entry.c_str());
+ std::string guid = GetGUID(path_entry.c_str());
+ pathGuidMap.insert(std::make_pair(*pathIt, guid));
+ pathCountMap[*pathIt] = 1;
+ if( pathAndSubPaths.size() == 1 ||
+ lastPartOfPath == "test" )
+ {
+ // This is a directory off the root so lets make sure it gets used
+ pathCountMap[*pathIt] = 10;
+ }
+ } else {
+ ++pathCountMap[*pathIt];
+ }
+ }
+ }
+
+ // Write out all of the new projects, one per unique path component
+ for (pathGuidIter = pathGuidMap.begin(); pathGuidIter != pathGuidMap.end(); ++pathGuidIter)
+ {
+ std::string path = pathGuidIter->first;
+ std::string guid = pathGuidIter->second;
+ std::string lastPartOfPath = lastPathComponent(path);
+ if ( /*lastPartOfPath == "test" || */
+ (lastPartOfPath != "." && pathCountMap[path] > 1 ) )
+ {
+ fout << "Project(\"" << "{2150E333-8FDC-42A3-9474-1A3956D46DE8}" << "\") = \""
+ << lastPartOfPath << "\", \"" << lastPartOfPath << "\", \"{" << guid << "}\"\n";
+ fout << "EndProject\n";
+
+ std::string parentPath = allButLastPathComponent(path);
+ if (parentPath != path)
+ {
+ std::string path_entry = std::string("SOLUTION FOLDER: ") + parentPath;
+ std::string parentGuid = GetGUID(path_entry.c_str());
+ nestedProjects.push_back(std::make_pair(guid, parentGuid));
+ }
+ }
+ }
+
+
+ std::vector<cmLocalGenerator*>& children = root->GetChildren();
+ std::vector<cmLocalGenerator*>::iterator it;
+ for (it = children.begin(); it != children.end(); ++it) {
+ cmLocalGenerator* lg = *it;
+ std::string rl = lg->Convert("", cmLocalGenerator::START, cmLocalGenerator::SHELL, true);
+ }
+
+ 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
+ std::vector<std::string> dspnames = static_cast<cmLocalVisualStudio7Generator *>(generators[i])->GetCreatedProjectNames();
+ cmTargets &tgts = pg->GetMakefile()->GetTargets();
+ cmTargets::iterator l = tgts.begin();
+ std::string dir = mf->GetStartDirectory();
+
+ for( std::vector<std::string>::iterator si = dspnames.begin();
+ l != tgts.end() && si != dspnames.end(); l)
+ {
+ if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) {
+ // TODO
+ // Does this matter for the organization? Perhaps we could group them
+ // under an External Projects folder
+ } else if ( (l->second.GetType() != cmTarget::INSTALL_FILES) &&
+ (l->second.GetType() != cmTarget::INSTALL_PROGRAMS) )
+ {
+ if (si->c_str() != "") {
+ std::map<std::string, std::string>::iterator pathGuidIter;
+ std::string path = generators[0]->Convert(dir.c_str(), cmLocalGenerator::START);
+ std::vector<std::string> pathAndSubPaths = buildPathAndSubPathVector(path);
+
+ // Find the path that we want to use for the project based on if the count is > 1
+ for( std::vector<std::string>::reverse_iterator subDirIt = pathAndSubPaths.rbegin();
+ subDirIt != pathAndSubPaths.rend(); ++subDirIt )
+ {
+ std::string subDirPath = *subDirIt;
+ if ( pathCountMap[subDirPath] > 1 ){
+ path = *subDirIt;
+ }
+ }
+
+ pathGuidIter = pathGuidMap.find(path);
+ if (pathGuidIter != pathGuidMap.end()) {
+ // This find is to make sure we don't add things like RUN_TESTS
+ std::map<std::string, std::string>::iterator dspIter;
+ dspIter = dspPathMap.find(si->c_str());
+ if (dspIter != dspPathMap.end()) {
+ std::string projGuid = GetGUID(si->c_str());
+ std::string pathGuid = pathGuidIter->second;
+ nestedProjects.push_back(std::make_pair(projGuid, pathGuid));
+ } else {
+ // Perhaps add it to some Default folder.. ?
+ }
+ }
+ }
+ }
+ ++si;
+ }
+ }
+ }
+}
+
+ //----------------------------------------------------------------------------
+ void cmGlobalVisualStudio8Generator::WriteAdditionalGlobalSections(
+ std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+ {
+ bool nestSolutionFolders =
+ cmSystemTools::IsOn(root->GetMakefile()->GetDefinition("NEST_SOLUTION_FOLDERS"));
+ nestSolutionFolders = true;
+
+ if (nestSolutionFolders)
+ {
+ fout << "\tGlobalSection(NestedProjects) = preSolution\n";
+ std::vector<std::pair<std::string, std::string> >::iterator npIter;
+ for (npIter = nestedProjects.begin(); npIter != nestedProjects.end(); ++npIter)
+ {
+ fout << "\t\t{" << npIter->first << "} = {" << npIter->second << "}\n";
+ }
+ fout << "\tEndGlobalSection\n";
+ }
+ }
+
+ //----------------------------------------------------------------------------
void cmGlobalVisualStudio8Generator::WriteSLNFile(
std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
+ // Reset nestedProjects
+ nestedProjects.clear();
+
// Make all targets depend on their respective project's build
// system check target.
unsigned int i;
diff -w -u cmake-2.6.3/Source/cmGlobalVisualStudio8Generator.h trunk/Source/cmGlobalVisualStudio8Generator.h
--- cmake-2.6.3/Source/cmGlobalVisualStudio8Generator.h 2009-02-21 14:17:00.000000000 -0800
+++ trunk/Source/cmGlobalVisualStudio8Generator.h 2008-09-25 16:14:00.963441600 -0700
@@ -76,6 +76,15 @@
virtual void WriteProjectConfigurations(std::ostream& fout,
const char* name,
bool partOfDefaultBuild);
+
+ virtual void WriteAdditionalGlobalSections(std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+
+ virtual void WriteAdditionalProjectSections(std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+
+ std::vector<std::pair<std::string, std::string> > nestedProjects;
+
std::string PlatformName; // Win32 or x64
};
#endif
diff -w -u cmake-2.6.3/Source/cmLocalVisualStudio7Generator.cxx trunk/Source/cmLocalVisualStudio7Generator.cxx
--- cmake-2.6.3/Source/cmLocalVisualStudio7Generator.cxx 2009-02-21 14:17:00.000000000 -0800
+++ trunk/Source/cmLocalVisualStudio7Generator.cxx 2009-03-13 14:12:33.928866500 -0700
@@ -201,11 +201,14 @@
void cmLocalVisualStudio7Generator
::CreateSingleVCProj(const char *lname, cmTarget &target)
{
+ // add to the list of projects
+ std::string pname = lname;
+ this->CreatedProjectNames.push_back(pname);
+
this->FortranProject =
static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
->TargetIsFortranOnly(target);
- // add to the list of projects
- std::string pname = lname;
+
target.SetProperty("GENERATOR_FILE_NAME",lname);
// create the dsp.cmake file
std::string fname;
diff -w -u cmake-2.6.3/Source/cmLocalVisualStudio7Generator.h trunk/Source/cmLocalVisualStudio7Generator.h
--- cmake-2.6.3/Source/cmLocalVisualStudio7Generator.h 2009-02-21 14:17:00.000000000 -0800
+++ trunk/Source/cmLocalVisualStudio7Generator.h 2008-09-25 16:13:48.072899100 -0700
@@ -66,6 +66,15 @@
std::vector<std::string>&
dirs);
+ /**
+ * Return array of created DSP names in a STL vector.
+ * Each executable must have its own dsp.
+ */
+ std::vector<std::string> GetCreatedProjectNames()
+ {
+ return this->CreatedProjectNames;
+ }
+
void SetExtraFlagTable(cmVS7FlagTable const* table)
{ this->ExtraFlagTable = table; }
private:
@@ -125,6 +134,7 @@
cmVS7FlagTable const* ExtraFlagTable;
std::string ModuleDefinitionFile;
+ std::vector<std::string> CreatedProjectNames;
int Version;
bool FortranProject;
std::string PlatformName; // Win32 or x64
|