Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmGlobalVisualStudio7Generator.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "windows.h" // this must be first to define GetCurrentDirectory
13 #include "cmGlobalVisualStudio7Generator.h"
14 #include "cmGeneratedFileStream.h"
15 #include "cmLocalVisualStudio7Generator.h"
16 #include "cmMakefile.h"
17 #include "cmake.h"
18
19 cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator()
20 {
21   this->FindMakeProgramFile = "CMakeVS7FindMake.cmake";
22 }
23
24
25 void cmGlobalVisualStudio7Generator
26 ::EnableLanguage(std::vector<std::string>const &  lang, 
27                  cmMakefile *mf, bool optional)
28 {
29   mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
30   mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
31   mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
32   mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
33   mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort");
34   this->AddPlatformDefinitions(mf);
35   
36   // Create list of configurations requested by user's cache, if any.
37   this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
38   this->GenerateConfigurations(mf);
39   
40   // if this environment variable is set, then copy it to
41   // a static cache entry.  It will be used by 
42   // cmLocalGenerator::ConstructScript, to add an extra PATH
43   // to all custom commands.   This is because the VS IDE
44   // does not use the environment it is run in, and this allows
45   // for running commands and using dll's that the IDE environment
46   // does not know about.
47   const char* extraPath = cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH");
48   if(extraPath)
49     {
50     mf->AddCacheDefinition
51       ("CMAKE_MSVCIDE_RUN_PATH", extraPath, 
52        "Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
53        cmCacheManager::STATIC);
54     }
55
56 }
57
58 void cmGlobalVisualStudio7Generator::AddPlatformDefinitions(cmMakefile* mf)
59 {
60   mf->AddDefinition("MSVC70", "1");
61   mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86");
62   mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86");
63 }
64
65 std::string cmGlobalVisualStudio7Generator
66 ::GenerateBuildCommand(const char* makeProgram,
67                        const char *projectName, 
68                        const char* additionalOptions, const char *targetName,
69                        const char* config, bool ignoreErrors, bool)
70 {
71   // Ingoring errors is not implemented in visual studio 6
72   (void) ignoreErrors;
73
74   // now build the test
75   std::string makeCommand = 
76     cmSystemTools::ConvertToOutputPath(makeProgram);
77   std::string lowerCaseCommand = makeCommand;
78   cmSystemTools::LowerCase(lowerCaseCommand);
79
80   // if there are spaces in the makeCommand, assume a full path
81   // and convert it to a path with no spaces in it as the
82   // RunSingleCommand does not like spaces
83 #if defined(_WIN32) && !defined(__CYGWIN__)      
84   if(makeCommand.find(' ') != std::string::npos)
85     {
86     cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
87     }
88 #endif
89   makeCommand += " ";
90   makeCommand += projectName;
91   makeCommand += ".sln ";
92   bool clean = false;
93   if ( targetName && strcmp(targetName, "clean") == 0 )
94     {
95     clean = true;
96     targetName = "ALL_BUILD";
97     }
98   if(clean)
99     {
100     makeCommand += "/clean ";
101     }
102   else
103     {
104     makeCommand += "/build ";
105     }
106
107   if(config && strlen(config))
108     {
109     makeCommand += config;
110     }
111   else
112     {
113     makeCommand += "Debug";
114     }
115   makeCommand += " /project ";
116
117   if (targetName && strlen(targetName))
118     {
119     makeCommand += targetName;
120     }
121   else
122     {
123     makeCommand += "ALL_BUILD";
124     }
125   if ( additionalOptions )
126     {
127     makeCommand += " ";
128     makeCommand += additionalOptions;
129     }
130   return makeCommand;
131 }
132
133 ///! Create a local generator appropriate to this Global Generator
134 cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator()
135 {
136   cmLocalVisualStudio7Generator *lg =
137     new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS7);
138   lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
139   lg->SetGlobalGenerator(this);
140   return lg;
141 }
142
143 void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
144 {
145   // process the configurations
146   const char* ct 
147     = this->CMakeInstance->GetCacheDefinition("CMAKE_CONFIGURATION_TYPES");
148   if ( ct )
149     {
150     std::vector<std::string> argsOut;
151     cmSystemTools::ExpandListArgument(ct, argsOut);
152     for(std::vector<std::string>::iterator i = argsOut.begin();
153         i != argsOut.end(); ++i)
154       {
155       if(std::find(this->Configurations.begin(), 
156                    this->Configurations.end(),
157                    *i) == this->Configurations.end())
158         {
159         this->Configurations.push_back(*i);
160         }
161       }
162     }
163   // default to at least Debug and Release
164   if(this->Configurations.size() == 0)
165     {
166     this->Configurations.push_back("Debug");
167     this->Configurations.push_back("Release");
168     }
169   
170   // Reset the entry to have a semi-colon separated list.
171   std::string configs = this->Configurations[0];
172   for(unsigned int i=1; i < this->Configurations.size(); ++i)
173     {
174     configs += ";";
175     configs += this->Configurations[i];
176     }
177
178   mf->AddCacheDefinition(
179     "CMAKE_CONFIGURATION_TYPES",
180     configs.c_str(),
181     "Semicolon separated list of supported configuration types, "
182     "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
183     "anything else will be ignored.",
184     cmCacheManager::STRING);
185 }
186
187 void cmGlobalVisualStudio7Generator::Generate()
188 {
189   // first do the superclass method
190   this->cmGlobalVisualStudioGenerator::Generate();
191
192   // Now write out the DSW
193   this->OutputSLNFile();
194   // If any solution or project files changed during the generation,
195   // tell Visual Studio to reload them...
196   if(!cmSystemTools::GetErrorOccuredFlag())
197     {
198     this->CallVisualStudioMacro(MacroReload);
199     }
200 }
201
202 void cmGlobalVisualStudio7Generator
203 ::OutputSLNFile(cmLocalGenerator* root,
204                 std::vector<cmLocalGenerator*>& generators)
205 {
206   if(generators.size() == 0)
207     {
208     return;
209     }
210   this->CurrentProject = root->GetMakefile()->GetProjectName();
211   std::string fname = root->GetMakefile()->GetStartOutputDirectory();
212   fname += "/";
213   fname += root->GetMakefile()->GetProjectName();
214   fname += ".sln";
215   cmGeneratedFileStream fout(fname.c_str());
216   fout.SetCopyIfDifferent(true);
217   if(!fout)
218     {
219     return;
220     }
221   this->WriteSLNFile(fout, root, generators);
222   if (fout.Close())
223     {
224     this->FileReplacedDuringGenerate(fname);
225     }
226 }
227
228 // output the SLN file
229 void cmGlobalVisualStudio7Generator::OutputSLNFile()
230 {
231   std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
232   for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
233     {
234     this->OutputSLNFile(it->second[0], it->second);
235     }
236 }
237
238
239 void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
240   std::ostream& fout, 
241   cmLocalGenerator* root,
242   OrderedTargetDependSet const& projectTargets)
243 {
244   // loop over again and write out configurations for each target
245   // in the solution
246   for(OrderedTargetDependSet::const_iterator tt =
247         projectTargets.begin(); tt != projectTargets.end(); ++tt)
248     {
249     cmTarget* target = *tt;
250     const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
251     if(expath)
252       {
253       this->WriteProjectConfigurations(
254         fout, target->GetName(),
255         true, target->GetProperty("VS_PLATFORM_MAPPING"));
256       }
257     else
258       {
259       bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
260         root->GetMakefile()->GetProjectName(), target);
261       const char *vcprojName = 
262         target->GetProperty("GENERATOR_FILE_NAME");
263       if (vcprojName)
264         {
265         this->WriteProjectConfigurations(fout, vcprojName,
266                                          partOfDefaultBuild);
267         }
268       }
269     }
270 }
271
272
273 void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
274     std::ostream& fout,
275     cmLocalGenerator* root,
276     OrderedTargetDependSet const& projectTargets)
277 {
278   for(OrderedTargetDependSet::const_iterator tt =
279         projectTargets.begin(); tt != projectTargets.end(); ++tt)
280     {
281     cmTarget* target = *tt;
282     bool written = false;
283
284     // handle external vc project files
285     const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
286     if(expath)
287       {
288       std::string project = target->GetName();
289       std::string location = expath;
290
291       this->WriteExternalProject(fout,
292                                  project.c_str(),
293                                  location.c_str(),
294                                  target->GetProperty("VS_PROJECT_TYPE"),
295                                  target->GetUtilities());
296       written = true;
297       }
298     else
299       {
300       const char *vcprojName =
301         target->GetProperty("GENERATOR_FILE_NAME");
302       if(vcprojName)
303         {
304         cmMakefile* tmf = target->GetMakefile();
305         std::string dir = tmf->GetStartOutputDirectory();
306         dir = root->Convert(dir.c_str(),
307                             cmLocalGenerator::START_OUTPUT);
308         if(dir == ".")
309           {
310           dir = ""; // msbuild cannot handle ".\" prefix
311           }
312         this->WriteProject(fout, vcprojName, dir.c_str(),
313                            *target);
314         written = true;
315         }
316       }
317
318     // Create "solution folder" information from FOLDER target property
319     //
320     if (written && this->UseFolderProperty())
321       {
322       const char *targetFolder = target->GetProperty("FOLDER");
323       if (targetFolder)
324         {
325         std::vector<cmsys::String> tokens =
326           cmSystemTools::SplitString(targetFolder, '/', false);
327
328         std::string cumulativePath = "";
329
330         for(std::vector<cmsys::String>::iterator iter = tokens.begin();
331             iter != tokens.end(); ++iter)
332           {
333           if(!iter->size())
334             {
335             continue;
336             }
337
338           if (cumulativePath.empty())
339             {
340             cumulativePath = "CMAKE_FOLDER_GUID_" + *iter;
341             }
342           else
343             {
344             VisualStudioFolders[cumulativePath].insert(
345               cumulativePath + "/" + *iter);
346
347             cumulativePath = cumulativePath + "/" + *iter;
348             }
349
350           this->CreateGUID(cumulativePath.c_str());
351           }
352
353         if (!cumulativePath.empty())
354           {
355           VisualStudioFolders[cumulativePath].insert(target->GetName());
356           }
357         }
358       }
359     }
360 }
361
362
363 void cmGlobalVisualStudio7Generator::WriteTargetDepends(
364     std::ostream& fout,
365     OrderedTargetDependSet const& projectTargets
366     )
367 {
368   for(OrderedTargetDependSet::const_iterator tt =
369         projectTargets.begin(); tt != projectTargets.end(); ++tt)
370     {
371     cmTarget* target = *tt;
372     cmMakefile* mf = target->GetMakefile(); 
373     const char *vcprojName = 
374       target->GetProperty("GENERATOR_FILE_NAME");
375     if (vcprojName)
376       { 
377       std::string dir = mf->GetStartDirectory();
378       this->WriteProjectDepends(fout, vcprojName, 
379                                 dir.c_str(), *target);
380       }
381     }
382 }
383
384 //----------------------------------------------------------------------------
385 // Write a SLN file to the stream
386 void cmGlobalVisualStudio7Generator
387 ::WriteSLNFile(std::ostream& fout,
388                cmLocalGenerator* root,
389                std::vector<cmLocalGenerator*>& generators)
390 {
391   // Write out the header for a SLN file
392   this->WriteSLNHeader(fout);
393
394   // Collect all targets under this root generator and the transitive
395   // closure of their dependencies.
396   TargetDependSet projectTargets;
397   TargetDependSet originalTargets;
398   this->GetTargetSets(projectTargets, originalTargets, root, generators);
399   OrderedTargetDependSet orderedProjectTargets(projectTargets);
400
401   this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
402
403   bool useFolderProperty = this->UseFolderProperty();
404   if (useFolderProperty)
405     {
406     this->WriteFolders(fout);
407     }
408
409   // Write out the configurations information for the solution
410   fout << "Global\n"
411        << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
412   
413   int c = 0;
414   for(std::vector<std::string>::iterator i = this->Configurations.begin();
415       i != this->Configurations.end(); ++i)
416     {
417     fout << "\t\tConfigName." << c << " = " << *i << "\n";
418     c++;
419     }
420   fout << "\tEndGlobalSection\n";
421   // Write out project(target) depends 
422   fout << "\tGlobalSection(ProjectDependencies) = postSolution\n";
423   this->WriteTargetDepends(fout, orderedProjectTargets);
424   fout << "\tEndGlobalSection\n";
425
426   if (useFolderProperty)
427     {
428     // Write out project folders
429     fout << "\tGlobalSection(NestedProjects) = preSolution\n";
430     this->WriteFoldersContent(fout);
431     fout << "\tEndGlobalSection\n";
432     }
433
434   // Write out the configurations for all the targets in the project
435   fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
436   this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
437   fout << "\tEndGlobalSection\n";
438
439   // Write the footer for the SLN file
440   this->WriteSLNFooter(fout);
441 }
442
443 //----------------------------------------------------------------------------
444 void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout)
445 {
446   const char *prefix = "CMAKE_FOLDER_GUID_";
447   const std::string::size_type skip_prefix = strlen(prefix);
448   std::string guidProjectTypeFolder = "2150E333-8FDC-42A3-9474-1A3956D46DE8";
449   for(std::map<std::string,std::set<std::string> >::iterator iter =
450     VisualStudioFolders.begin(); iter != VisualStudioFolders.end(); ++iter)
451     {
452     std::string fullName = iter->first;
453     std::string guid = this->GetGUID(fullName.c_str());
454
455     cmSystemTools::ReplaceString(fullName, "/", "\\");
456     if (cmSystemTools::StringStartsWith(fullName.c_str(), prefix))
457       {
458       fullName = fullName.substr(skip_prefix);
459       }
460
461     std::string nameOnly = cmSystemTools::GetFilenameName(fullName);
462
463     fout << "Project(\"{" <<
464       guidProjectTypeFolder << "}\") = \"" <<
465       nameOnly << "\", \"" <<
466       fullName << "\", \"{" <<
467       guid <<
468       "}\"\nEndProject\n";
469     }
470 }
471
472 //----------------------------------------------------------------------------
473 void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout)
474 {
475   for(std::map<std::string,std::set<std::string> >::iterator iter =
476     VisualStudioFolders.begin(); iter != VisualStudioFolders.end(); ++iter)
477     {
478     std::string key(iter->first);
479     std::string guidParent(this->GetGUID(key.c_str()));
480
481     for(std::set<std::string>::iterator it = iter->second.begin();
482         it != iter->second.end(); ++it)
483       {
484       std::string value(*it);
485       std::string guid(this->GetGUID(value.c_str()));
486
487       fout << "\t\t{" << guid << "} = {" << guidParent << "}\n";
488       }
489     }
490 }
491
492 //----------------------------------------------------------------------------
493 std::string
494 cmGlobalVisualStudio7Generator::ConvertToSolutionPath(const char* path)
495 {
496   // Convert to backslashes.  Do not use ConvertToOutputPath because
497   // we will add quoting ourselves, and we know these projects always
498   // use windows slashes.
499   std::string d = path;
500   std::string::size_type pos = 0;
501   while((pos = d.find('/', pos)) != d.npos)
502     {
503     d[pos++] = '\\';
504     }
505   return d;
506 }
507
508 // Write a dsp file into the SLN file,
509 // Note, that dependencies from executables to 
510 // the libraries it uses are also done here
511 void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout, 
512                                const char* dspname,
513                                const char* dir, cmTarget& target)
514
515    // check to see if this is a fortran build
516   const char* ext = ".vcproj";
517   const char* project =
518     "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
519   if(this->TargetIsFortranOnly(target))
520     {
521     ext = ".vfproj";
522     project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
523     }
524
525   fout << project
526        << dspname << "\", \""
527        << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
528        << dspname << ext << "\", \"{"
529        << this->GetGUID(dspname) << "}\"\nEndProject\n";
530
531   UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
532   if(ui != this->UtilityDepends.end())
533     {
534     const char* uname = ui->second.c_str();
535     fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
536          << uname << "\", \""
537          << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
538          << uname << ".vcproj" << "\", \"{"
539          << this->GetGUID(uname) << "}\"\n"
540          << "EndProject\n";
541     }
542 }
543
544
545
546 // Write a dsp file into the SLN file,
547 // Note, that dependencies from executables to 
548 // the libraries it uses are also done here
549 void
550 cmGlobalVisualStudio7Generator
551 ::WriteProjectDepends(std::ostream& fout,
552                       const char* dspname,
553                       const char*, cmTarget& target)
554 {
555   int depcount = 0;
556   std::string dspguid = this->GetGUID(dspname);
557   VSDependSet const& depends = this->VSTargetDepends[&target];
558   for(VSDependSet::const_iterator di = depends.begin();
559       di != depends.end(); ++di)
560     {
561     const char* name = di->c_str();
562     std::string guid = this->GetGUID(name);
563     if(guid.size() == 0)
564       {
565       std::string m = "Target: ";
566       m += target.GetName();
567       m += " depends on unknown target: ";
568       m += name;
569       cmSystemTools::Error(m.c_str());
570       }
571     fout << "\t\t{" << dspguid << "}." << depcount << " = {" << guid << "}\n";
572     depcount++;
573     }
574
575   UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
576   if(ui != this->UtilityDepends.end())
577     {
578     const char* uname = ui->second.c_str();
579     fout << "\t\t{" << this->GetGUID(uname) << "}.0 = {" << dspguid << "}\n";
580     }
581 }
582
583
584 // Write a dsp file into the SLN file, Note, that dependencies from
585 // executables to the libraries it uses are also done here
586 void cmGlobalVisualStudio7Generator
587 ::WriteProjectConfigurations(std::ostream& fout, const char* name,
588                              bool partOfDefaultBuild,
589                              const char* platformMapping)
590 {
591   std::string guid = this->GetGUID(name);
592   for(std::vector<std::string>::iterator i = this->Configurations.begin();
593       i != this->Configurations.end(); ++i)
594     {
595     fout << "\t\t{" << guid << "}." << *i
596          << ".ActiveCfg = " << *i << "|"
597          << (platformMapping ? platformMapping : "Win32") << "\n";
598     if(partOfDefaultBuild)
599       {
600       fout << "\t\t{" << guid << "}." << *i
601            << ".Build.0 = " << *i << "|"
602            << (platformMapping ? platformMapping : "Win32") << "\n";
603       }
604     }
605 }
606
607
608
609 // Write a dsp file into the SLN file,
610 // Note, that dependencies from executables to 
611 // the libraries it uses are also done here
612 void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout, 
613                                const char* name,
614                                const char* location,
615                                const char* typeGuid,
616                                const std::set<cmStdString>&)
617
618   std::string d = cmSystemTools::ConvertToOutputPath(location);
619   fout << "Project("
620        << "\"{"
621        << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942")
622        << "}\") = \""
623        << name << "\", \""
624        << this->ConvertToSolutionPath(location) << "\", \"{"
625        << this->GetGUID(name)
626        << "}\"\n";
627   fout << "EndProject\n";
628 }
629
630
631
632 // Standard end of dsw file
633 void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout)
634 {
635   fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
636        << "\tEndGlobalSection\n"
637        << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
638        << "\tEndGlobalSection\n"
639        << "EndGlobal\n";
640 }
641
642   
643 // ouput standard header for dsw file
644 void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout)
645 {
646   fout << "Microsoft Visual Studio Solution File, Format Version 7.00\n";
647 }
648
649 //----------------------------------------------------------------------------
650 std::string
651 cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget* target)
652 {
653   std::string pname = target->GetName();
654   pname += "_UTILITY";
655   std::string fname = target->GetMakefile()->GetStartOutputDirectory();
656   fname += "/";
657   fname += pname;
658   fname += ".vcproj";
659   cmGeneratedFileStream fout(fname.c_str());
660   fout.SetCopyIfDifferent(true);
661   this->CreateGUID(pname.c_str());
662   std::string guid = this->GetGUID(pname.c_str());
663
664   fout <<
665     "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
666     "<VisualStudioProject\n"
667     "\tProjectType=\"Visual C++\"\n"
668     "\tVersion=\"" << this->GetIDEVersion() << "0\"\n"
669     "\tName=\"" << pname << "\"\n"
670     "\tProjectGUID=\"{" << guid << "}\"\n"
671     "\tKeyword=\"Win32Proj\">\n"
672     "\t<Platforms><Platform Name=\"Win32\"/></Platforms>\n"
673     "\t<Configurations>\n"
674     ;
675   for(std::vector<std::string>::iterator i = this->Configurations.begin();
676       i != this->Configurations.end(); ++i)
677     {
678     fout <<
679       "\t\t<Configuration\n"
680       "\t\t\tName=\"" << *i << "|Win32\"\n"
681       "\t\t\tOutputDirectory=\"" << *i << "\"\n"
682       "\t\t\tIntermediateDirectory=\"" << pname << ".dir\\" << *i << "\"\n"
683       "\t\t\tConfigurationType=\"10\"\n"
684       "\t\t\tUseOfMFC=\"0\"\n"
685       "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"
686       "\t\t\tCharacterSet=\"2\">\n"
687       "\t\t</Configuration>\n"
688       ;
689     }
690   fout <<
691     "\t</Configurations>\n"
692     "\t<Files></Files>\n"
693     "\t<Globals></Globals>\n"
694     "</VisualStudioProject>\n"
695     ;
696
697   if(fout.Close())
698     {
699     this->FileReplacedDuringGenerate(fname);
700     }
701   return pname;
702 }
703
704 std::string cmGlobalVisualStudio7Generator::GetGUID(const char* name)
705 {
706   std::string guidStoreName = name;
707   guidStoreName += "_GUID_CMAKE";
708   const char* storedGUID = 
709     this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
710   if(storedGUID)
711     {
712     return std::string(storedGUID);
713     }
714   cmSystemTools::Error("Unknown Target referenced : ",
715                        name);
716   return "";
717 }
718
719
720 void cmGlobalVisualStudio7Generator::CreateGUID(const char* name)
721 {
722   std::string guidStoreName = name;
723   guidStoreName += "_GUID_CMAKE";
724   if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
725     {
726     return;
727     }
728   std::string ret;
729   UUID uid;
730   unsigned char *uidstr;
731   UuidCreate(&uid);
732   UuidToString(&uid,&uidstr);
733   ret = reinterpret_cast<char*>(uidstr);
734   RpcStringFree(&uidstr);
735   ret = cmSystemTools::UpperCase(ret);
736   this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(), 
737                                      ret.c_str(), "Stored GUID", 
738                                      cmCacheManager::INTERNAL);
739 }
740
741 std::vector<std::string> *cmGlobalVisualStudio7Generator::GetConfigurations()
742 {
743   return &this->Configurations;
744 };
745
746 //----------------------------------------------------------------------------
747 void cmGlobalVisualStudio7Generator
748 ::GetDocumentation(cmDocumentationEntry& entry) const
749 {
750   entry.Name = this->GetName();
751   entry.Brief = "Generates Visual Studio .NET 2002 project files.";
752   entry.Full = "";
753 }
754
755 //----------------------------------------------------------------------------
756 void
757 cmGlobalVisualStudio7Generator
758 ::AppendDirectoryForConfig(const char* prefix,
759                            const char* config,
760                            const char* suffix,
761                            std::string& dir)
762 {
763   if(config)
764     {
765     dir += prefix;
766     dir += config;
767     dir += suffix;
768     }
769 }
770
771 bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
772                                                           cmTarget* target)
773 {
774   if(target->GetPropertyAsBool("EXCLUDE_FROM_DEFAULT_BUILD"))
775     {
776     return false;
777     }
778   // if it is a utilitiy target then only make it part of the 
779   // default build if another target depends on it
780   int type = target->GetType();
781   if (type == cmTarget::GLOBAL_TARGET)
782     {
783     return false;
784     }
785   if(type == cmTarget::UTILITY)
786     {
787     return this->IsDependedOn(project, target);
788     } 
789   // default is to be part of the build
790   return true;
791 }
792
793 //----------------------------------------------------------------------------
794 static cmVS7FlagTable cmVS7ExtraFlagTable[] =
795 {
796   // Precompiled header and related options.  Note that the
797   // UsePrecompiledHeader entries are marked as "Continue" so that the
798   // corresponding PrecompiledHeaderThrough entry can be found.
799   {"UsePrecompiledHeader", "YX", "Automatically Generate", "2",
800    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
801   {"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "",
802    cmVS7FlagTable::UserValueRequired},
803   {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3",
804    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
805   {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
806    cmVS7FlagTable::UserValueRequired},
807   {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "TRUE", 0},
808
809   // Exception handling mode.  If no entries match, it will be FALSE.
810   {"ExceptionHandling", "GX", "enable c++ exceptions", "TRUE", 0},
811   {"ExceptionHandling", "EHsc", "enable c++ exceptions", "TRUE", 0},
812   // The EHa option does not have an IDE setting.  Let it go to false,
813   // and have EHa passed on the command line by leaving out the table
814   // entry.
815
816   {0,0,0,0,0}
817 };
818 cmIDEFlagTable const* cmGlobalVisualStudio7Generator::GetExtraFlagTableVS7()
819 {
820   return cmVS7ExtraFlagTable;
821 }