Imported Upstream version 2.8.12.2
[platform/upstream/cmake.git] / Source / cmVisualStudio10TargetGenerator.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 "cmVisualStudio10TargetGenerator.h"
13 #include "cmGlobalVisualStudio10Generator.h"
14 #include "cmGeneratorTarget.h"
15 #include "cmTarget.h"
16 #include "cmComputeLinkInformation.h"
17 #include "cmGeneratedFileStream.h"
18 #include "cmMakefile.h"
19 #include "cmSourceFile.h"
20 #include "cmVisualStudioGeneratorOptions.h"
21 #include "cmLocalVisualStudio7Generator.h"
22 #include "cmVS10CLFlagTable.h"
23 #include "cmVS10LinkFlagTable.h"
24 #include "cmVS10LibFlagTable.h"
25 #include "cmVS11CLFlagTable.h"
26 #include "cmVS11LinkFlagTable.h"
27 #include "cmVS11LibFlagTable.h"
28 #include "cmVS12CLFlagTable.h"
29 #include "cmVS12LinkFlagTable.h"
30 #include "cmVS12LibFlagTable.h"
31
32 #include <cmsys/auto_ptr.hxx>
33
34 static cmVS7FlagTable const*
35 cmVSGetCLFlagTable(cmLocalVisualStudioGenerator* lg)
36 {
37   if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
38     { return cmVS12CLFlagTable; }
39   else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
40     { return cmVS11CLFlagTable; }
41   else
42     { return cmVS10CLFlagTable; }
43 }
44
45 static cmVS7FlagTable const*
46 cmVSGetLibFlagTable(cmLocalVisualStudioGenerator* lg)
47 {
48   if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
49     { return cmVS12LibFlagTable; }
50   else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
51     { return cmVS11LibFlagTable; }
52   else
53     { return cmVS10LibFlagTable; }
54 }
55
56 static cmVS7FlagTable const*
57 cmVSGetLinkFlagTable(cmLocalVisualStudioGenerator* lg)
58 {
59   if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
60     { return cmVS12LinkFlagTable; }
61   else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
62     { return cmVS11LinkFlagTable; }
63   else
64     { return cmVS10LinkFlagTable; }
65 }
66
67 static std::string cmVS10EscapeXML(std::string arg)
68 {
69   cmSystemTools::ReplaceString(arg, "&", "&amp;");
70   cmSystemTools::ReplaceString(arg, "<", "&lt;");
71   cmSystemTools::ReplaceString(arg, ">", "&gt;");
72   return arg;
73 }
74
75 static std::string cmVS10EscapeComment(std::string comment)
76 {
77   // MSBuild takes the CDATA of a <Message></Message> element and just
78   // does "echo $CDATA" with no escapes.  We must encode the string.
79   // http://technet.microsoft.com/en-us/library/cc772462%28WS.10%29.aspx
80   std::string echoable;
81   for(std::string::iterator c = comment.begin(); c != comment.end(); ++c)
82     {
83     switch (*c)
84       {
85       case '\r': break;
86       case '\n': echoable += '\t'; break;
87       case '"': /* no break */
88       case '|': /* no break */
89       case '&': /* no break */
90       case '<': /* no break */
91       case '>': /* no break */
92       case '^': echoable += '^'; /* no break */
93       default:  echoable += *c; break;
94       }
95     }
96   return echoable;
97 }
98
99 cmVisualStudio10TargetGenerator::
100 cmVisualStudio10TargetGenerator(cmTarget* target,
101                                 cmGlobalVisualStudio10Generator* gg)
102 {
103   this->GlobalGenerator = gg;
104   this->Target = target;
105   this->GeneratorTarget = gg->GetGeneratorTarget(target);
106   this->Makefile = target->GetMakefile();
107   this->LocalGenerator =
108     (cmLocalVisualStudio7Generator*)
109     this->Makefile->GetLocalGenerator();
110   this->Name = this->Target->GetName();
111   this->GlobalGenerator->CreateGUID(this->Name.c_str());
112   this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
113   this->Platform = gg->GetPlatformName();
114   this->BuildFileStream = 0;
115 }
116
117 cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
118 {
119   for(OptionsMap::iterator i = this->ClOptions.begin();
120       i != this->ClOptions.end(); ++i)
121     {
122     delete i->second;
123     }
124   for(OptionsMap::iterator i = this->LinkOptions.begin();
125       i != this->LinkOptions.end(); ++i)
126     {
127     delete i->second;
128     }
129   if(!this->BuildFileStream)
130     {
131     return;
132     }
133   if (this->BuildFileStream->Close())
134     {
135     this->GlobalGenerator
136       ->FileReplacedDuringGenerate(this->PathToVcxproj);
137     }
138   delete this->BuildFileStream;
139 }
140
141 void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
142   const char* tag,
143   const char* config,
144   int indentLevel,
145   const char* attribute,
146   const char* end,
147   std::ostream* stream)
148
149 {
150   if(!stream)
151     {
152     stream = this->BuildFileStream;
153     }
154   stream->fill(' ');
155   stream->width(indentLevel*2 );
156   (*stream ) << "";
157   (*stream ) << "<" << tag
158              << " Condition=\"'$(Configuration)|$(Platform)'=='";
159   (*stream ) << config << "|" << this->Platform << "'\"";
160   if(attribute)
161     {
162     (*stream ) << attribute;
163     }
164   // close the tag
165   (*stream ) << ">";
166   if(end)
167     {
168     (*stream ) << end;
169     }
170 }
171
172 void cmVisualStudio10TargetGenerator::WriteString(const char* line,
173                                                   int indentLevel)
174 {
175   this->BuildFileStream->fill(' ');
176   this->BuildFileStream->width(indentLevel*2 );
177   // write an empty string to get the fill level indent to print
178   (*this->BuildFileStream ) << "";
179   (*this->BuildFileStream ) << line;
180 }
181
182 #define VS10_USER_PROPS "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props"
183
184 void cmVisualStudio10TargetGenerator::Generate()
185 {
186   // do not generate external ms projects
187   if(this->Target->GetProperty("EXTERNAL_MSPROJECT"))
188     {
189     return;
190     }
191   // Tell the global generator the name of the project file
192   this->Target->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str());
193   this->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
194                             ".vcxproj");
195   if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
196     {
197     if(!this->ComputeClOptions())
198       {
199       return;
200       }
201     if(!this->ComputeLinkOptions())
202       {
203       return;
204       }
205     }
206   cmMakefile* mf = this->Target->GetMakefile();
207   std::string path =  mf->GetStartOutputDirectory();
208   path += "/";
209   path += this->Name;
210   path += ".vcxproj";
211   this->BuildFileStream =
212     new cmGeneratedFileStream(path.c_str());
213   this->PathToVcxproj = path;
214   this->BuildFileStream->SetCopyIfDifferent(true);
215
216   // Write the encoding header into the file
217   char magic[] = {0xEF,0xBB, 0xBF};
218   this->BuildFileStream->write(magic, 3);
219
220   //get the tools version to use
221   const std::string toolsVer(this->GlobalGenerator->GetToolsVersion());
222   std::string project_defaults="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
223   project_defaults.append("<Project DefaultTargets=\"Build\" ToolsVersion=\"");
224   project_defaults.append(toolsVer +"\" ");
225   project_defaults.append(
226           "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
227   this->WriteString(project_defaults.c_str(),0);
228
229   this->WriteProjectConfigurations();
230   this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1);
231   this->WriteString("<ProjectGUID>", 2);
232   (*this->BuildFileStream) <<  "{" << this->GUID << "}</ProjectGUID>\n";
233
234   const char* vsProjectTypes =
235     this->Target->GetProperty("VS_GLOBAL_PROJECT_TYPES");
236   if(vsProjectTypes)
237     {
238     this->WriteString("<ProjectTypes>", 2);
239     (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectTypes) <<
240       "</ProjectTypes>\n";
241     }
242
243   const char* vsProjectName = this->Target->GetProperty("VS_SCC_PROJECTNAME");
244   const char* vsLocalPath = this->Target->GetProperty("VS_SCC_LOCALPATH");
245   const char* vsProvider = this->Target->GetProperty("VS_SCC_PROVIDER");
246
247   if( vsProjectName && vsLocalPath && vsProvider )
248     {
249     this->WriteString("<SccProjectName>", 2);
250     (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectName) <<
251       "</SccProjectName>\n";
252     this->WriteString("<SccLocalPath>", 2);
253     (*this->BuildFileStream) << cmVS10EscapeXML(vsLocalPath) <<
254       "</SccLocalPath>\n";
255     this->WriteString("<SccProvider>", 2);
256     (*this->BuildFileStream) << cmVS10EscapeXML(vsProvider) <<
257       "</SccProvider>\n";
258
259     const char* vsAuxPath = this->Target->GetProperty("VS_SCC_AUXPATH");
260     if( vsAuxPath )
261       {
262       this->WriteString("<SccAuxPath>", 2);
263        (*this->BuildFileStream) << cmVS10EscapeXML(vsAuxPath) <<
264          "</SccAuxPath>\n";
265       }
266     }
267
268   const char* vsGlobalKeyword =
269     this->Target->GetProperty("VS_GLOBAL_KEYWORD");
270   if(!vsGlobalKeyword)
271     {
272     this->WriteString("<Keyword>Win32Proj</Keyword>\n", 2);
273     }
274   else
275     {
276     this->WriteString("<Keyword>", 2);
277     (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalKeyword) <<
278       "</Keyword>\n";
279     }
280
281   const char* vsGlobalRootNamespace =
282     this->Target->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
283   if(vsGlobalRootNamespace)
284     {
285     this->WriteString("<RootNamespace>", 2);
286     (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalRootNamespace) <<
287       "</RootNamespace>\n";
288     }
289
290   this->WriteString("<Platform>", 2);
291   (*this->BuildFileStream) << this->Platform << "</Platform>\n";
292   const char* projLabel = this->Target->GetProperty("PROJECT_LABEL");
293   if(!projLabel)
294     {
295     projLabel = this->Name.c_str();
296     }
297   this->WriteString("<ProjectName>", 2);
298   (*this->BuildFileStream) << projLabel << "</ProjectName>\n";
299   if(const char* targetFrameworkVersion = this->Target->GetProperty(
300        "VS_DOTNET_TARGET_FRAMEWORK_VERSION"))
301     {
302     this->WriteString("<TargetFrameworkVersion>", 2);
303     (*this->BuildFileStream) << targetFrameworkVersion
304                              << "</TargetFrameworkVersion>\n";
305     }
306   this->WriteString("</PropertyGroup>\n", 1);
307   this->WriteString("<Import Project="
308                     "\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n",
309                     1);
310   this->WriteProjectConfigurationValues();
311   this->WriteString(
312     "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n", 1);
313   this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1);
314   if (this->GlobalGenerator->IsMasmEnabled())
315     {
316     this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
317                       "BuildCustomizations\\masm.props\" />\n", 2);
318     }
319   this->WriteString("</ImportGroup>\n", 1);
320   this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1);
321   this->WriteString("<Import Project=\"" VS10_USER_PROPS "\""
322                     " Condition=\"exists('" VS10_USER_PROPS "')\""
323                     " Label=\"LocalAppDataPlatform\" />", 2);
324   this->WriteString("</ImportGroup>\n", 1);
325   this->WriteString("<PropertyGroup Label=\"UserMacros\" />\n", 1);
326   this->WritePathAndIncrementalLinkOptions();
327   this->WriteItemDefinitionGroups();
328   this->WriteCustomCommands();
329   this->WriteAllSources();
330   this->WriteDotNetReferences();
331   this->WriteEmbeddedResourceGroup();
332   this->WriteWinRTReferences();
333   this->WriteProjectReferences();
334   this->WriteString(
335     "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\""
336     " />\n", 1);
337   this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
338   if (this->GlobalGenerator->IsMasmEnabled())
339     {
340     this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
341                       "BuildCustomizations\\masm.targets\" />\n", 2);
342     }
343   this->WriteString("</ImportGroup>\n", 1);
344   this->WriteString("</Project>", 0);
345   // The groups are stored in a separate file for VS 10
346   this->WriteGroups();
347 }
348
349 void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
350 {
351   std::vector<std::string> references;
352   if(const char* vsDotNetReferences =
353      this->Target->GetProperty("VS_DOTNET_REFERENCES"))
354     {
355     cmSystemTools::ExpandListArgument(vsDotNetReferences, references);
356     }
357   if(!references.empty())
358     {
359     this->WriteString("<ItemGroup>\n", 1);
360     for(std::vector<std::string>::iterator ri = references.begin();
361         ri != references.end(); ++ri)
362       {
363       this->WriteString("<Reference Include=\"", 2);
364       (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n";
365       this->WriteString("<CopyLocalSatelliteAssemblies>true"
366                         "</CopyLocalSatelliteAssemblies>\n", 3);
367       this->WriteString("<ReferenceOutputAssembly>true"
368                         "</ReferenceOutputAssembly>\n", 3);
369       this->WriteString("</Reference>\n", 2);
370       }
371     this->WriteString("</ItemGroup>\n", 1);
372     }
373 }
374
375 void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
376 {
377   std::vector<cmSourceFile*> const& resxObjs =
378     this->GeneratorTarget->ResxSources;
379   if(!resxObjs.empty())
380     {
381     this->WriteString("<ItemGroup>\n", 1);
382     for(std::vector<cmSourceFile*>::const_iterator oi = resxObjs.begin();
383         oi != resxObjs.end(); ++oi)
384       {
385       std::string obj = (*oi)->GetFullPath();
386       this->WriteString("<EmbeddedResource Include=\"", 2);
387       this->ConvertToWindowsSlash(obj);
388       (*this->BuildFileStream ) << obj << "\">\n";
389
390       this->WriteString("<DependentUpon>", 3);
391       std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h";
392       (*this->BuildFileStream ) << hFileName;
393       this->WriteString("</DependentUpon>\n", 3);
394
395       std::vector<std::string> const * configs =
396         this->GlobalGenerator->GetConfigurations();
397       for(std::vector<std::string>::const_iterator i = configs->begin();
398           i != configs->end(); ++i)
399         {
400         this->WritePlatformConfigTag("LogicalName", i->c_str(), 3);
401         if(this->Target->GetProperty("VS_GLOBAL_ROOTNAMESPACE"))
402           {
403           (*this->BuildFileStream ) << "$(RootNamespace).";
404           }
405         (*this->BuildFileStream ) << "%(Filename)";
406         (*this->BuildFileStream ) << ".resources";
407         (*this->BuildFileStream ) << "</LogicalName>\n";
408         }
409
410       this->WriteString("</EmbeddedResource>\n", 2);
411       }
412     this->WriteString("</ItemGroup>\n", 1);
413     }
414 }
415
416 void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
417 {
418   std::vector<std::string> references;
419   if(const char* vsWinRTReferences =
420      this->Target->GetProperty("VS_WINRT_REFERENCES"))
421     {
422     cmSystemTools::ExpandListArgument(vsWinRTReferences, references);
423     }
424   if(!references.empty())
425     {
426     this->WriteString("<ItemGroup>\n", 1);
427     for(std::vector<std::string>::iterator ri = references.begin();
428         ri != references.end(); ++ri)
429       {
430       this->WriteString("<Reference Include=\"", 2);
431       (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n";
432       this->WriteString("<IsWinMDFile>true</IsWinMDFile>\n", 3);
433       this->WriteString("</Reference>\n", 2);
434       }
435     this->WriteString("</ItemGroup>\n", 1);
436     }
437 }
438
439 // ConfigurationType Application, Utility StaticLibrary DynamicLibrary
440
441 void cmVisualStudio10TargetGenerator::WriteProjectConfigurations()
442 {
443   this->WriteString("<ItemGroup Label=\"ProjectConfigurations\">\n", 1);
444   std::vector<std::string> *configs =
445     static_cast<cmGlobalVisualStudio7Generator *>
446     (this->GlobalGenerator)->GetConfigurations();
447   for(std::vector<std::string>::iterator i = configs->begin();
448       i != configs->end(); ++i)
449     {
450     this->WriteString("<ProjectConfiguration Include=\"", 2);
451     (*this->BuildFileStream ) <<  *i << "|" << this->Platform << "\">\n";
452     this->WriteString("<Configuration>", 3);
453     (*this->BuildFileStream ) <<  *i << "</Configuration>\n";
454     this->WriteString("<Platform>", 3);
455     (*this->BuildFileStream) << this->Platform << "</Platform>\n";
456     this->WriteString("</ProjectConfiguration>\n", 2);
457     }
458   this->WriteString("</ItemGroup>\n", 1);
459 }
460
461 void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
462 {
463   cmGlobalVisualStudio10Generator* gg =
464     static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
465   std::vector<std::string> *configs =
466     static_cast<cmGlobalVisualStudio7Generator *>
467     (this->GlobalGenerator)->GetConfigurations();
468   for(std::vector<std::string>::iterator i = configs->begin();
469       i != configs->end(); ++i)
470     {
471     this->WritePlatformConfigTag("PropertyGroup",
472                                  i->c_str(),
473                                  1, " Label=\"Configuration\"", "\n");
474     std::string configType = "<ConfigurationType>";
475     switch(this->Target->GetType())
476       {
477       case cmTarget::SHARED_LIBRARY:
478       case cmTarget::MODULE_LIBRARY:
479         configType += "DynamicLibrary";
480         break;
481       case cmTarget::OBJECT_LIBRARY:
482       case cmTarget::STATIC_LIBRARY:
483         configType += "StaticLibrary";
484         break;
485       case cmTarget::EXECUTABLE:
486         configType += "Application";
487         break;
488       case cmTarget::UTILITY:
489         configType += "Utility";
490         break;
491       case cmTarget::GLOBAL_TARGET:
492       case cmTarget::UNKNOWN_LIBRARY:
493         break;
494       }
495     configType += "</ConfigurationType>\n";
496     this->WriteString(configType.c_str(), 2);
497
498     const char* mfcFlag =
499       this->Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG");
500     std::string mfcFlagValue = mfcFlag ? mfcFlag : "0";
501
502     std::string useOfMfcValue = "false";
503     if(mfcFlagValue == "1")
504       {
505       useOfMfcValue = "Static";
506       }
507     else if(mfcFlagValue == "2")
508       {
509       useOfMfcValue = "Dynamic";
510       }
511     std::string mfcLine = "<UseOfMfc>";
512     mfcLine += useOfMfcValue + "</UseOfMfc>\n";
513     this->WriteString(mfcLine.c_str(), 2);
514
515     if((this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
516        this->ClOptions[*i]->UsingUnicode()) ||
517        this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
518       {
519       this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2);
520       }
521     else if (this->Target->GetType() <= cmTarget::MODULE_LIBRARY &&
522        this->ClOptions[*i]->UsingSBCS())
523       {
524       this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2);
525       }
526     else
527       {
528       this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2);
529       }
530     if(const char* toolset = gg->GetPlatformToolset())
531       {
532       std::string pts = "<PlatformToolset>";
533       pts += toolset;
534       pts += "</PlatformToolset>\n";
535       this->WriteString(pts.c_str(), 2);
536       }
537     if(this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
538       {
539       this->WriteString("<WindowsAppContainer>true"
540                         "</WindowsAppContainer>\n", 2);
541       }
542
543     this->WriteString("</PropertyGroup>\n", 1);
544     }
545 }
546
547 void cmVisualStudio10TargetGenerator::WriteCustomCommands()
548 {
549   this->SourcesVisited.clear();
550   for(std::vector<cmSourceFile*>::const_iterator
551         si = this->GeneratorTarget->CustomCommands.begin();
552       si != this->GeneratorTarget->CustomCommands.end(); ++si)
553     {
554     this->WriteCustomCommand(*si);
555     }
556 }
557
558 //----------------------------------------------------------------------------
559 void cmVisualStudio10TargetGenerator::WriteCustomCommand(cmSourceFile* sf)
560 {
561   if(this->SourcesVisited.insert(sf).second)
562     {
563     if(std::vector<cmSourceFile*> const* depends =
564        this->Target->GetSourceDepends(sf))
565       {
566       for(std::vector<cmSourceFile*>::const_iterator di = depends->begin();
567           di != depends->end(); ++di)
568         {
569         this->WriteCustomCommand(*di);
570         }
571       }
572     if(cmCustomCommand const* command = sf->GetCustomCommand())
573       {
574       this->WriteString("<ItemGroup>\n", 1);
575       this->WriteCustomRule(sf, *command);
576       this->WriteString("</ItemGroup>\n", 1);
577       }
578     }
579 }
580
581 void
582 cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
583                                                  cmCustomCommand const &
584                                                  command)
585 {
586   std::string sourcePath = source->GetFullPath();
587   // VS 10 will always rebuild a custom command attached to a .rule
588   // file that doesn't exist so create the file explicitly.
589   if (source->GetPropertyAsBool("__CMAKE_RULE"))
590     {
591     if(!cmSystemTools::FileExists(sourcePath.c_str()))
592       {
593       // Make sure the path exists for the file
594       std::string path = cmSystemTools::GetFilenamePath(sourcePath);
595       cmSystemTools::MakeDirectory(path.c_str());
596       std::ofstream fout(sourcePath.c_str());
597       if(fout)
598         {
599         fout << "# generated from CMake\n";
600         fout.flush();
601         fout.close();
602         }
603       else
604         {
605         std::string error = "Could not create file: [";
606         error +=  sourcePath;
607         error += "]  ";
608         cmSystemTools::Error
609           (error.c_str(), cmSystemTools::GetLastSystemError().c_str());
610         }
611       }
612     }
613   cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
614   std::string comment = lg->ConstructComment(command);
615   comment = cmVS10EscapeComment(comment);
616   std::vector<std::string> *configs =
617     static_cast<cmGlobalVisualStudio7Generator *>
618     (this->GlobalGenerator)->GetConfigurations();
619
620   this->WriteSource("CustomBuild", source, ">\n");
621
622   for(std::vector<std::string>::iterator i = configs->begin();
623       i != configs->end(); ++i)
624     {
625     std::string script =
626       cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
627     this->WritePlatformConfigTag("Message",i->c_str(), 3);
628     (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
629     this->WritePlatformConfigTag("Command", i->c_str(), 3);
630     (*this->BuildFileStream ) << script << "</Command>\n";
631     this->WritePlatformConfigTag("AdditionalInputs", i->c_str(), 3);
632
633     (*this->BuildFileStream ) << source->GetFullPath();
634     for(std::vector<std::string>::const_iterator d =
635           command.GetDepends().begin();
636         d != command.GetDepends().end();
637         ++d)
638       {
639       std::string dep;
640       if(this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep))
641         {
642         this->ConvertToWindowsSlash(dep);
643         (*this->BuildFileStream ) << ";" << dep;
644         }
645       }
646     (*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n";
647     this->WritePlatformConfigTag("Outputs", i->c_str(), 3);
648     const char* sep = "";
649     for(std::vector<std::string>::const_iterator o =
650           command.GetOutputs().begin();
651         o != command.GetOutputs().end();
652         ++o)
653       {
654       std::string out = *o;
655       this->ConvertToWindowsSlash(out);
656       (*this->BuildFileStream ) << sep << out;
657       sep = ";";
658       }
659     (*this->BuildFileStream ) << "</Outputs>\n";
660     if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
661       {
662       // VS >= 11 let us turn off linking of custom command outputs.
663       this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3);
664       (*this->BuildFileStream ) << "false</LinkObjects>\n";
665       }
666     }
667   this->WriteString("</CustomBuild>\n", 2);
668 }
669
670 std::string
671 cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path,
672                                              bool forceRelative)
673 {
674   return forceRelative
675     ? cmSystemTools::RelativePath(
676       this->Makefile->GetCurrentOutputDirectory(), path.c_str())
677     : this->LocalGenerator->Convert(path.c_str(),
678                                     cmLocalGenerator::START_OUTPUT,
679                                     cmLocalGenerator::UNCHANGED);
680 }
681
682 void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
683 {
684   // first convert all of the slashes
685   std::string::size_type pos = 0;
686   while((pos = s.find('/', pos)) != std::string::npos)
687     {
688     s[pos] = '\\';
689     pos++;
690     }
691 }
692 void cmVisualStudio10TargetGenerator::WriteGroups()
693 {
694   // collect up group information
695   std::vector<cmSourceGroup> sourceGroups =
696     this->Makefile->GetSourceGroups();
697   std::vector<cmSourceFile*>  classes = this->Target->GetSourceFiles();
698
699   std::set<cmSourceGroup*> groupsUsed;
700   for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
701       s != classes.end(); s++)
702     {
703     cmSourceFile* sf = *s;
704     std::string const& source = sf->GetFullPath();
705     cmSourceGroup& sourceGroup =
706       this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
707     groupsUsed.insert(&sourceGroup);
708     }
709
710   this->AddMissingSourceGroups(groupsUsed, sourceGroups);
711
712   // Write out group file
713   std::string path =  this->Makefile->GetStartOutputDirectory();
714   path += "/";
715   path += this->Name;
716   path += ".vcxproj.filters";
717   cmGeneratedFileStream fout(path.c_str());
718   fout.SetCopyIfDifferent(true);
719   char magic[] = {0xEF,0xBB, 0xBF};
720   fout.write(magic, 3);
721   cmGeneratedFileStream* save = this->BuildFileStream;
722   this->BuildFileStream = & fout;
723
724   //get the tools version to use
725   const std::string toolsVer(this->GlobalGenerator->GetToolsVersion());
726   std::string project_defaults="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
727   project_defaults.append("<Project ToolsVersion=\"");
728   project_defaults.append(toolsVer +"\" ");
729   project_defaults.append(
730         "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
731   this->WriteString(project_defaults.c_str(),0);
732
733   for(ToolSourceMap::const_iterator ti = this->Tools.begin();
734       ti != this->Tools.end(); ++ti)
735     {
736     this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups);
737     }
738
739   std::vector<cmSourceFile*> const& resxObjs =
740     this->GeneratorTarget->ResxSources;
741   if(!resxObjs.empty())
742     {
743     this->WriteString("<ItemGroup>\n", 1);
744     for(std::vector<cmSourceFile*>::const_iterator oi = resxObjs.begin();
745         oi != resxObjs.end(); ++oi)
746       {
747       std::string obj = (*oi)->GetFullPath();
748       this->WriteString("<EmbeddedResource Include=\"", 2);
749       this->ConvertToWindowsSlash(obj);
750       (*this->BuildFileStream ) << obj << "\">\n";
751       this->WriteString("<Filter>Resource Files</Filter>\n", 3);
752       this->WriteString("</EmbeddedResource>\n", 2);
753       }
754     this->WriteString("</ItemGroup>\n", 1);
755     }
756
757   // Add object library contents as external objects.
758   std::vector<std::string> objs;
759   this->GeneratorTarget->UseObjectLibraries(objs);
760   if(!objs.empty())
761     {
762     this->WriteString("<ItemGroup>\n", 1);
763     for(std::vector<std::string>::const_iterator
764           oi = objs.begin(); oi != objs.end(); ++oi)
765       {
766       std::string obj = *oi;
767       this->WriteString("<Object Include=\"", 2);
768       this->ConvertToWindowsSlash(obj);
769       (*this->BuildFileStream ) << obj << "\">\n";
770       this->WriteString("<Filter>Object Libraries</Filter>\n", 3);
771       this->WriteString("</Object>\n", 2);
772       }
773     this->WriteString("</ItemGroup>\n", 1);
774     }
775
776   this->WriteString("<ItemGroup>\n", 1);
777   for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
778       g != groupsUsed.end(); ++g)
779     {
780     cmSourceGroup* sg = *g;
781     const char* name = sg->GetFullName();
782     if(strlen(name) != 0)
783       {
784       this->WriteString("<Filter Include=\"", 2);
785       (*this->BuildFileStream) << name << "\">\n";
786       std::string guidName = "SG_Filter_";
787       guidName += name;
788       this->GlobalGenerator->CreateGUID(guidName.c_str());
789       this->WriteString("<UniqueIdentifier>", 3);
790       std::string guid
791         = this->GlobalGenerator->GetGUID(guidName.c_str());
792       (*this->BuildFileStream)
793         << "{"
794         << guid << "}"
795         << "</UniqueIdentifier>\n";
796       this->WriteString("</Filter>\n", 2);
797       }
798     }
799   if(!objs.empty())
800     {
801     this->WriteString("<Filter Include=\"Object Libraries\">\n", 2);
802     std::string guidName = "SG_Filter_Object Libraries";
803     this->GlobalGenerator->CreateGUID(guidName.c_str());
804     this->WriteString("<UniqueIdentifier>", 3);
805     std::string guid =
806       this->GlobalGenerator->GetGUID(guidName.c_str());
807     (*this->BuildFileStream) << "{" << guid << "}"
808                              << "</UniqueIdentifier>\n";
809     this->WriteString("</Filter>\n", 2);
810     }
811
812   if(!this->GeneratorTarget->ResxSources.empty())
813     {
814     this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
815     std::string guidName = "SG_Filter_Resource Files";
816     this->GlobalGenerator->CreateGUID(guidName.c_str());
817     this->WriteString("<UniqueIdentifier>", 3);
818     std::string guid =
819       this->GlobalGenerator->GetGUID(guidName.c_str());
820     (*this->BuildFileStream) << "{" << guid << "}"
821                              << "</UniqueIdentifier>\n";
822     this->WriteString("<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;", 3);
823     (*this->BuildFileStream) << "gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;";
824     (*this->BuildFileStream) << "mfcribbon-ms</Extensions>\n";
825     this->WriteString("</Filter>\n", 2);
826   }
827
828   this->WriteString("</ItemGroup>\n", 1);
829   this->WriteString("</Project>\n", 0);
830   // restore stream pointer
831   this->BuildFileStream = save;
832
833   if (fout.Close())
834     {
835     this->GlobalGenerator->FileReplacedDuringGenerate(path);
836     }
837 }
838
839 // Add to groupsUsed empty source groups that have non-empty children.
840 void
841 cmVisualStudio10TargetGenerator::AddMissingSourceGroups(
842   std::set<cmSourceGroup*>& groupsUsed,
843   const std::vector<cmSourceGroup>& allGroups
844   )
845 {
846   for(std::vector<cmSourceGroup>::const_iterator current = allGroups.begin();
847       current != allGroups.end(); ++current)
848     {
849     std::vector<cmSourceGroup> const& children = current->GetGroupChildren();
850     if(children.empty())
851       {
852       continue; // the group is really empty
853       }
854
855     this->AddMissingSourceGroups(groupsUsed, children);
856
857     cmSourceGroup* current_ptr = const_cast<cmSourceGroup*>(&(*current));
858     if(groupsUsed.find(current_ptr) != groupsUsed.end())
859       {
860       continue; // group has already been added to set
861       }
862
863     // check if it least one of the group's descendants is not empty
864     // (at least one child must already have been added)
865     std::vector<cmSourceGroup>::const_iterator child_it = children.begin();
866     while(child_it != children.end())
867       {
868       cmSourceGroup* child_ptr = const_cast<cmSourceGroup*>(&(*child_it));
869       if(groupsUsed.find(child_ptr) != groupsUsed.end())
870         {
871         break; // found a child that was already added => add current group too
872         }
873       child_it++;
874       }
875
876     if(child_it == children.end())
877       {
878       continue; // no descendants have source files => ignore this group
879       }
880
881     groupsUsed.insert(current_ptr);
882     }
883 }
884
885 void
886 cmVisualStudio10TargetGenerator::
887 WriteGroupSources(const char* name,
888                   ToolSources const& sources,
889                   std::vector<cmSourceGroup>& sourceGroups)
890 {
891   this->WriteString("<ItemGroup>\n", 1);
892   for(ToolSources::const_iterator s = sources.begin();
893       s != sources.end(); ++s)
894     {
895     cmSourceFile* sf = s->SourceFile;
896     std::string const& source = sf->GetFullPath();
897     cmSourceGroup& sourceGroup =
898       this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
899     const char* filter = sourceGroup.GetFullName();
900     this->WriteString("<", 2);
901     std::string path = this->ConvertPath(source, s->RelativePath);
902     this->ConvertToWindowsSlash(path);
903     (*this->BuildFileStream) << name << " Include=\""
904                              << path;
905     if(strlen(filter))
906       {
907       (*this->BuildFileStream) << "\">\n";
908       this->WriteString("<Filter>", 3);
909       (*this->BuildFileStream) << filter << "</Filter>\n";
910       this->WriteString("</", 2);
911       (*this->BuildFileStream) << name << ">\n";
912       }
913     else
914       {
915       (*this->BuildFileStream) << "\" />\n";
916       }
917     }
918   this->WriteString("</ItemGroup>\n", 1);
919 }
920
921 void cmVisualStudio10TargetGenerator::WriteSource(
922   const char* tool, cmSourceFile* sf, const char* end)
923 {
924   // Visual Studio tools append relative paths to the current dir, as in:
925   //
926   //  c:\path\to\current\dir\..\..\..\relative\path\to\source.c
927   //
928   // and fail if this exceeds the maximum allowed path length.  Our path
929   // conversion uses full paths outside the build tree to allow deeper trees.
930   bool forceRelative = false;
931   std::string sourceFile = this->ConvertPath(sf->GetFullPath(), false);
932   if(this->LocalGenerator->GetVersion() == cmLocalVisualStudioGenerator::VS10
933      && cmSystemTools::FileIsFullPath(sourceFile.c_str()))
934     {
935     // Normal path conversion resulted in a full path.  VS 10 (but not 11)
936     // refuses to show the property page in the IDE for a source file with a
937     // full path (not starting in a '.' or '/' AFAICT).  CMake <= 2.8.4 used a
938     // relative path but to allow deeper build trees CMake 2.8.[5678] used a
939     // full path except for custom commands.  Custom commands do not work
940     // without a relative path, but they do not seem to be involved in tools
941     // with the above behavior.  For other sources we now use a relative path
942     // when the combined path will not be too long so property pages appear.
943     std::string sourceRel = this->ConvertPath(sf->GetFullPath(), true);
944     size_t const maxLen = 250;
945     if(sf->GetCustomCommand() ||
946        ((strlen(this->Makefile->GetCurrentOutputDirectory()) + 1 +
947          sourceRel.length()) <= maxLen))
948       {
949       forceRelative = true;
950       sourceFile = sourceRel;
951       }
952     else
953       {
954       this->GlobalGenerator->PathTooLong(this->Target, sf, sourceRel);
955       }
956     }
957   this->ConvertToWindowsSlash(sourceFile);
958   this->WriteString("<", 2);
959   (*this->BuildFileStream ) << tool << " Include=\"" << sourceFile << "\"";
960
961   if(sf->GetExtension() == "h" &&
962     this->IsResxHeader(sf->GetFullPath()))
963     {
964       (*this->BuildFileStream ) << ">\n";
965       this->WriteString("<FileType>CppForm</FileType>\n", 3);
966       this->WriteString("</ClInclude>\n", 2);
967     }
968   else
969     {
970       (*this->BuildFileStream ) << (end? end : " />\n");
971     }
972
973   ToolSource toolSource = {sf, forceRelative};
974   this->Tools[tool].push_back(toolSource);
975 }
976
977 void cmVisualStudio10TargetGenerator::WriteSources(
978   const char* tool, std::vector<cmSourceFile*> const& sources)
979 {
980   for(std::vector<cmSourceFile*>::const_iterator
981         si = sources.begin(); si != sources.end(); ++si)
982     {
983     this->WriteSource(tool, *si);
984     }
985 }
986
987 void cmVisualStudio10TargetGenerator::WriteAllSources()
988 {
989   if(this->Target->GetType() > cmTarget::UTILITY)
990     {
991     return;
992     }
993   this->WriteString("<ItemGroup>\n", 1);
994
995   this->WriteSources("ClInclude", this->GeneratorTarget->HeaderSources);
996   this->WriteSources("Midl", this->GeneratorTarget->IDLSources);
997
998   for(std::vector<cmSourceFile*>::const_iterator
999         si = this->GeneratorTarget->ObjectSources.begin();
1000       si != this->GeneratorTarget->ObjectSources.end(); ++si)
1001     {
1002     const char* lang = (*si)->GetLanguage();
1003     const char* tool = NULL;
1004     if (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") == 0)
1005       {
1006       tool = "ClCompile";
1007       }
1008     else if (strcmp(lang, "ASM_MASM") == 0 &&
1009              this->GlobalGenerator->IsMasmEnabled())
1010       {
1011       tool = "MASM";
1012       }
1013     else if (strcmp(lang, "RC") == 0)
1014       {
1015       tool = "ResourceCompile";
1016       }
1017
1018     if (tool)
1019       {
1020       this->WriteSource(tool, *si, " ");
1021       if (this->OutputSourceSpecificFlags(*si))
1022         {
1023         this->WriteString("</", 2);
1024         (*this->BuildFileStream ) << tool << ">\n";
1025         }
1026       else
1027         {
1028         (*this->BuildFileStream ) << " />\n";
1029         }
1030       }
1031     else
1032       {
1033       this->WriteSource("None", *si);
1034       }
1035     }
1036
1037   if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
1038     {
1039     // For VS >= 11 we use LinkObjects to avoid linking custom command
1040     // outputs.  Use Object for all external objects, generated or not.
1041     this->WriteSources("Object", this->GeneratorTarget->ExternalObjects);
1042     }
1043   else
1044     {
1045     // If an object file is generated in this target, then vs10 will use
1046     // it in the build, and we have to list it as None instead of Object.
1047     for(std::vector<cmSourceFile*>::const_iterator
1048           si = this->GeneratorTarget->ExternalObjects.begin();
1049         si != this->GeneratorTarget->ExternalObjects.end(); ++si)
1050       {
1051       std::vector<cmSourceFile*> const* d=this->Target->GetSourceDepends(*si);
1052       this->WriteSource((d && !d->empty())? "None":"Object", *si);
1053       }
1054     }
1055
1056   this->WriteSources("None", this->GeneratorTarget->ExtraSources);
1057
1058   // Add object library contents as external objects.
1059   std::vector<std::string> objs;
1060   this->GeneratorTarget->UseObjectLibraries(objs);
1061   for(std::vector<std::string>::const_iterator
1062         oi = objs.begin(); oi != objs.end(); ++oi)
1063     {
1064     std::string obj = *oi;
1065     this->WriteString("<Object Include=\"", 2);
1066     this->ConvertToWindowsSlash(obj);
1067     (*this->BuildFileStream ) << obj << "\" />\n";
1068     }
1069
1070   this->WriteString("</ItemGroup>\n", 1);
1071 }
1072
1073 bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
1074   cmSourceFile* source)
1075 {
1076   cmSourceFile& sf = *source;
1077
1078   std::string objectName;
1079   if(this->GeneratorTarget->ExplicitObjectName.find(&sf)
1080      != this->GeneratorTarget->ExplicitObjectName.end())
1081     {
1082     objectName = this->GeneratorTarget->Objects[&sf];
1083     }
1084   std::string flags;
1085   std::string defines;
1086   if(const char* cflags = sf.GetProperty("COMPILE_FLAGS"))
1087     {
1088     flags += cflags;
1089     }
1090   if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS"))
1091     {
1092     defines += cdefs;
1093     }
1094   const char* lang =
1095     this->GlobalGenerator->GetLanguageFromExtension
1096     (sf.GetExtension().c_str());
1097   const char* sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
1098   const char* linkLanguage = this->Target->GetLinkerLanguage();
1099   bool needForceLang = false;
1100   // source file does not match its extension language
1101   if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
1102     {
1103     needForceLang = true;
1104     lang = sourceLang;
1105     }
1106   // if the source file does not match the linker language
1107   // then force c or c++
1108   if(needForceLang || (linkLanguage && lang
1109                        && strcmp(lang, linkLanguage) != 0))
1110     {
1111     if(strcmp(lang, "CXX") == 0)
1112       {
1113       // force a C++ file type
1114       flags += " /TP ";
1115       }
1116     else if(strcmp(lang, "C") == 0)
1117       {
1118       // force to c
1119       flags += " /TC ";
1120       }
1121     }
1122   bool hasFlags = false;
1123   // for the first time we need a new line if there is something
1124   // produced here.
1125   const char* firstString = ">\n";
1126   if(objectName.size())
1127     {
1128     (*this->BuildFileStream ) << firstString;
1129     firstString = "";
1130     hasFlags = true;
1131     this->WriteString("<ObjectFileName>", 3);
1132     (*this->BuildFileStream )
1133       << "$(IntDir)/" << objectName << "</ObjectFileName>\n";
1134     }
1135   std::vector<std::string> *configs =
1136     static_cast<cmGlobalVisualStudio7Generator *>
1137     (this->GlobalGenerator)->GetConfigurations();
1138   for( std::vector<std::string>::iterator config = configs->begin();
1139        config != configs->end(); ++config)
1140     {
1141     std::string configUpper = cmSystemTools::UpperCase(*config);
1142     std::string configDefines = defines;
1143     std::string defPropName = "COMPILE_DEFINITIONS_";
1144     defPropName += configUpper;
1145     if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
1146       {
1147       if(configDefines.size())
1148         {
1149         configDefines += ";";
1150         }
1151       configDefines += ccdefs;
1152       }
1153     // if we have flags or defines for this config then
1154     // use them
1155     if(flags.size() || configDefines.size())
1156       {
1157       (*this->BuildFileStream ) << firstString;
1158       firstString = ""; // only do firstString once
1159       hasFlags = true;
1160       cmVisualStudioGeneratorOptions
1161         clOptions(this->LocalGenerator,
1162                   cmVisualStudioGeneratorOptions::Compiler,
1163                   cmVSGetCLFlagTable(this->LocalGenerator), 0, this);
1164       clOptions.Parse(flags.c_str());
1165       clOptions.AddDefines(configDefines.c_str());
1166       clOptions.SetConfiguration((*config).c_str());
1167       clOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
1168       clOptions.OutputFlagMap(*this->BuildFileStream, "      ");
1169       clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream,
1170                                               "      ", "\n", lang);
1171       }
1172     }
1173   return hasFlags;
1174 }
1175
1176
1177 void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
1178 {
1179   cmTarget::TargetType ttype = this->Target->GetType();
1180   if(ttype > cmTarget::GLOBAL_TARGET)
1181     {
1182     return;
1183     }
1184
1185   this->WriteString("<PropertyGroup>\n", 2);
1186   this->WriteString("<_ProjectFileVersion>10.0.20506.1"
1187                     "</_ProjectFileVersion>\n", 3);
1188   std::vector<std::string> *configs =
1189     static_cast<cmGlobalVisualStudio7Generator *>
1190     (this->GlobalGenerator)->GetConfigurations();
1191   for(std::vector<std::string>::iterator config = configs->begin();
1192       config != configs->end(); ++config)
1193     {
1194     if(ttype >= cmTarget::UTILITY)
1195       {
1196       this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
1197       *this->BuildFileStream
1198         << "$(Platform)\\$(Configuration)\\$(ProjectName)\\"
1199         << "</IntDir>\n";
1200       }
1201     else
1202       {
1203       std::string intermediateDir = this->LocalGenerator->
1204         GetTargetDirectory(*this->Target);
1205       intermediateDir += "/";
1206       intermediateDir += *config;
1207       intermediateDir += "/";
1208       std::string outDir;
1209       std::string targetNameFull;
1210       if(ttype == cmTarget::OBJECT_LIBRARY)
1211         {
1212         outDir = intermediateDir;
1213         targetNameFull = this->Target->GetName();
1214         targetNameFull += ".lib";
1215         }
1216       else
1217         {
1218         outDir = this->Target->GetDirectory(config->c_str()) + "/";
1219         targetNameFull = this->Target->GetFullName(config->c_str());
1220         }
1221       this->ConvertToWindowsSlash(intermediateDir);
1222       this->ConvertToWindowsSlash(outDir);
1223
1224       this->WritePlatformConfigTag("OutDir", config->c_str(), 3);
1225       *this->BuildFileStream << outDir
1226                              << "</OutDir>\n";
1227
1228       this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
1229       *this->BuildFileStream << intermediateDir
1230                              << "</IntDir>\n";
1231
1232       this->WritePlatformConfigTag("TargetName", config->c_str(), 3);
1233       *this->BuildFileStream
1234         << cmSystemTools::GetFilenameWithoutLastExtension(
1235              targetNameFull.c_str())
1236         << "</TargetName>\n";
1237
1238       this->WritePlatformConfigTag("TargetExt", config->c_str(), 3);
1239       *this->BuildFileStream
1240         << cmSystemTools::GetFilenameLastExtension(targetNameFull.c_str())
1241         << "</TargetExt>\n";
1242
1243       this->OutputLinkIncremental(*config);
1244       }
1245     }
1246   this->WriteString("</PropertyGroup>\n", 2);
1247 }
1248
1249
1250
1251 void
1252 cmVisualStudio10TargetGenerator::
1253 OutputLinkIncremental(std::string const& configName)
1254 {
1255   // static libraries and things greater than modules do not need
1256   // to set this option
1257   if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
1258      || this->Target->GetType() > cmTarget::MODULE_LIBRARY)
1259     {
1260     return;
1261     }
1262   Options& linkOptions = *(this->LinkOptions[configName]);
1263
1264   const char* incremental = linkOptions.GetFlag("LinkIncremental");
1265   this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3);
1266   *this->BuildFileStream << (incremental?incremental:"true")
1267                          << "</LinkIncremental>\n";
1268   linkOptions.RemoveFlag("LinkIncremental");
1269
1270   const char* manifest = linkOptions.GetFlag("GenerateManifest");
1271   this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3);
1272   *this->BuildFileStream << (manifest?manifest:"true")
1273                          << "</GenerateManifest>\n";
1274   linkOptions.RemoveFlag("GenerateManifest");
1275
1276   // Some link options belong here.  Use them now and remove them so that
1277   // WriteLinkOptions does not use them.
1278   const char* flags[] = {
1279     "LinkDelaySign",
1280     "LinkKeyFile",
1281     0};
1282   for(const char** f = flags; *f; ++f)
1283     {
1284     const char* flag = *f;
1285     if(const char* value = linkOptions.GetFlag(flag))
1286       {
1287       this->WritePlatformConfigTag(flag, configName.c_str(), 3);
1288       *this->BuildFileStream << value << "</" << flag << ">\n";
1289       linkOptions.RemoveFlag(flag);
1290       }
1291     }
1292 }
1293
1294 //----------------------------------------------------------------------------
1295 bool cmVisualStudio10TargetGenerator::ComputeClOptions()
1296 {
1297   std::vector<std::string> const* configs =
1298     this->GlobalGenerator->GetConfigurations();
1299   for(std::vector<std::string>::const_iterator i = configs->begin();
1300       i != configs->end(); ++i)
1301     {
1302     if(!this->ComputeClOptions(*i))
1303       {
1304       return false;
1305       }
1306     }
1307   return true;
1308 }
1309
1310 //----------------------------------------------------------------------------
1311 bool cmVisualStudio10TargetGenerator::ComputeClOptions(
1312   std::string const& configName)
1313 {
1314   // much of this was copied from here:
1315   // copied from cmLocalVisualStudio7Generator.cxx 805
1316   // TODO: Integrate code below with cmLocalVisualStudio7Generator.
1317
1318   cmsys::auto_ptr<Options> pOptions(
1319     new Options(this->LocalGenerator, Options::Compiler,
1320                 cmVSGetCLFlagTable(this->LocalGenerator)));
1321   Options& clOptions = *pOptions;
1322
1323   std::string flags;
1324   // collect up flags for
1325   if(this->Target->GetType() < cmTarget::UTILITY)
1326     {
1327     const char* linkLanguage =
1328       this->Target->GetLinkerLanguage(configName.c_str());
1329     if(!linkLanguage)
1330       {
1331       cmSystemTools::Error
1332         ("CMake can not determine linker language for target: ",
1333          this->Name.c_str());
1334       return false;
1335       }
1336     if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
1337        || strcmp(linkLanguage, "Fortran") == 0)
1338       {
1339       std::string baseFlagVar = "CMAKE_";
1340       baseFlagVar += linkLanguage;
1341       baseFlagVar += "_FLAGS";
1342       flags = this->
1343         Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
1344       std::string flagVar = baseFlagVar + std::string("_") +
1345         cmSystemTools::UpperCase(configName);
1346       flags += " ";
1347       flags += this->
1348         Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
1349       }
1350     // set the correct language
1351     if(strcmp(linkLanguage, "C") == 0)
1352       {
1353       flags += " /TC ";
1354       }
1355     if(strcmp(linkLanguage, "CXX") == 0)
1356       {
1357       flags += " /TP ";
1358       }
1359     this->LocalGenerator->AddCompileOptions(flags, this->Target,
1360                                             linkLanguage, configName.c_str());
1361     }
1362
1363   // Get preprocessor definitions for this directory.
1364   std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags();
1365   clOptions.FixExceptionHandlingDefault();
1366   clOptions.AddFlag("PrecompiledHeader", "NotUsing");
1367   std::string asmLocation = configName + "/";
1368   clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
1369   clOptions.Parse(flags.c_str());
1370   clOptions.Parse(defineFlags.c_str());
1371   std::vector<std::string> targetDefines;
1372   this->Target->GetCompileDefinitions(targetDefines, configName.c_str());
1373   clOptions.AddDefines(targetDefines);
1374   clOptions.SetVerboseMakefile(
1375     this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
1376
1377   // Add a definition for the configuration name.
1378   std::string configDefine = "CMAKE_INTDIR=\"";
1379   configDefine += configName;
1380   configDefine += "\"";
1381   clOptions.AddDefine(configDefine);
1382   if(const char* exportMacro = this->Target->GetExportMacro())
1383     {
1384     clOptions.AddDefine(exportMacro);
1385     }
1386
1387   this->ClOptions[configName] = pOptions.release();
1388   return true;
1389 }
1390
1391 //----------------------------------------------------------------------------
1392 void cmVisualStudio10TargetGenerator::WriteClOptions(
1393   std::string const& configName,
1394   std::vector<std::string> const& includes)
1395 {
1396   Options& clOptions = *(this->ClOptions[configName]);
1397   this->WriteString("<ClCompile>\n", 2);
1398   clOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
1399   this->OutputIncludes(includes);
1400   clOptions.OutputFlagMap(*this->BuildFileStream, "      ");
1401
1402   // If not in debug mode, write the DebugInformationFormat field
1403   // without value so PDBs don't get generated uselessly.
1404   if(!clOptions.IsDebug())
1405     {
1406     this->WriteString("<DebugInformationFormat>"
1407                       "</DebugInformationFormat>\n", 3);
1408     }
1409
1410   clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
1411                                           "\n", "CXX");
1412   this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
1413   this->WriteString("</ClCompile>\n", 2);
1414 }
1415
1416 void cmVisualStudio10TargetGenerator::
1417 OutputIncludes(std::vector<std::string> const & includes)
1418 {
1419   this->WriteString("<AdditionalIncludeDirectories>", 3);
1420   for(std::vector<std::string>::const_iterator i =  includes.begin();
1421       i != includes.end(); ++i)
1422     {
1423     std::string incDir = *i;
1424     this->ConvertToWindowsSlash(incDir);
1425     *this->BuildFileStream << cmVS10EscapeXML(incDir) << ";";
1426     }
1427   this->WriteString("%(AdditionalIncludeDirectories)"
1428                     "</AdditionalIncludeDirectories>\n", 0);
1429 }
1430
1431
1432
1433 void cmVisualStudio10TargetGenerator::
1434 WriteRCOptions(std::string const& configName,
1435                std::vector<std::string> const & includes)
1436 {
1437   this->WriteString("<ResourceCompile>\n", 2);
1438   Options& clOptions = *(this->ClOptions[configName]);
1439   clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
1440                                           "\n", "RC");
1441   this->OutputIncludes(includes);
1442   this->WriteString("</ResourceCompile>\n", 2);
1443 }
1444
1445
1446 void
1447 cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
1448 {
1449   if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
1450     {
1451     return;
1452     }
1453   std::string libflags;
1454   this->LocalGenerator->GetStaticLibraryFlags(libflags,
1455     cmSystemTools::UpperCase(config), this->Target);
1456   if(!libflags.empty())
1457     {
1458     this->WriteString("<Lib>\n", 2);
1459     cmVisualStudioGeneratorOptions
1460       libOptions(this->LocalGenerator,
1461                  cmVisualStudioGeneratorOptions::Linker,
1462                  cmVSGetLibFlagTable(this->LocalGenerator), 0, this);
1463     libOptions.Parse(libflags.c_str());
1464     libOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
1465     libOptions.OutputFlagMap(*this->BuildFileStream, "      ");
1466     this->WriteString("</Lib>\n", 2);
1467     }
1468 }
1469
1470 //----------------------------------------------------------------------------
1471 bool cmVisualStudio10TargetGenerator::ComputeLinkOptions()
1472 {
1473   if(this->Target->GetType() == cmTarget::EXECUTABLE ||
1474      this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
1475      this->Target->GetType() == cmTarget::MODULE_LIBRARY)
1476     {
1477     std::vector<std::string> const* configs =
1478       this->GlobalGenerator->GetConfigurations();
1479     for(std::vector<std::string>::const_iterator i = configs->begin();
1480         i != configs->end(); ++i)
1481       {
1482       if(!this->ComputeLinkOptions(*i))
1483         {
1484         return false;
1485         }
1486       }
1487     }
1488   return true;
1489 }
1490
1491 //----------------------------------------------------------------------------
1492 bool
1493 cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
1494 {
1495   cmsys::auto_ptr<Options> pOptions(
1496     new Options(this->LocalGenerator, Options::Linker,
1497                 cmVSGetLinkFlagTable(this->LocalGenerator), 0, this));
1498   Options& linkOptions = *pOptions;
1499
1500   const char* linkLanguage =
1501     this->Target->GetLinkerLanguage(config.c_str());
1502   if(!linkLanguage)
1503     {
1504     cmSystemTools::Error
1505       ("CMake can not determine linker language for target: ",
1506        this->Name.c_str());
1507     return false;
1508     }
1509
1510   std::string CONFIG = cmSystemTools::UpperCase(config);
1511
1512   const char* linkType = "SHARED";
1513   if(this->Target->GetType() == cmTarget::MODULE_LIBRARY)
1514     {
1515     linkType = "MODULE";
1516     }
1517   if(this->Target->GetType() == cmTarget::EXECUTABLE)
1518     {
1519     linkType = "EXE";
1520     }
1521   std::string stackVar = "CMAKE_";
1522   stackVar += linkLanguage;
1523   stackVar += "_STACK_SIZE";
1524   const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
1525   std::string flags;
1526   if(stackVal)
1527     {
1528     flags += " /STACK:";
1529     flags += stackVal;
1530     }
1531   std::string linkFlagVarBase = "CMAKE_";
1532   linkFlagVarBase += linkType;
1533   linkFlagVarBase += "_LINKER_FLAGS";
1534   flags += " ";
1535   flags += this->
1536     Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str());
1537   std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
1538   flags += " ";
1539   flags += this->
1540     Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str());
1541   const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS");
1542   if(targetLinkFlags)
1543     {
1544     flags += " ";
1545     flags += targetLinkFlags;
1546     }
1547   std::string flagsProp = "LINK_FLAGS_";
1548   flagsProp += CONFIG;
1549   if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str()))
1550     {
1551     flags += " ";
1552     flags += flagsConfig;
1553     }
1554   if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
1555     {
1556     linkOptions.AddFlag("SubSystem", "Windows");
1557     }
1558   else
1559     {
1560     linkOptions.AddFlag("SubSystem", "Console");
1561     }
1562   std::string standardLibsVar = "CMAKE_";
1563   standardLibsVar += linkLanguage;
1564   standardLibsVar += "_STANDARD_LIBRARIES";
1565   std::string
1566     libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
1567   // Remove trailing spaces from libs
1568   std::string::size_type pos = libs.size()-1;
1569   if(libs.size() != 0)
1570     {
1571     while(libs[pos] == ' ')
1572       {
1573       pos--;
1574       }
1575     }
1576   if(pos != libs.size()-1)
1577     {
1578     libs = libs.substr(0, pos+1);
1579     }
1580   // Replace spaces in libs with ;
1581   cmSystemTools::ReplaceString(libs, " ", ";");
1582   cmComputeLinkInformation* pcli =
1583     this->Target->GetLinkInformation(config.c_str());
1584   if(!pcli)
1585     {
1586     cmSystemTools::Error
1587       ("CMake can not compute cmComputeLinkInformation for target: ",
1588        this->Name.c_str());
1589     return false;
1590     }
1591   // add the libraries for the target to libs string
1592   cmComputeLinkInformation& cli = *pcli;
1593   this->AddLibraries(cli, libs);
1594   linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
1595
1596   std::vector<std::string> const& ldirs = cli.GetDirectories();
1597   const char* sep = "";
1598   std::string linkDirs;
1599   for(std::vector<std::string>::const_iterator d = ldirs.begin();
1600       d != ldirs.end(); ++d)
1601     {
1602     // first just full path
1603     linkDirs += sep;
1604     linkDirs += *d;
1605     sep = ";";
1606     linkDirs += sep;
1607     // next path with configuration type Debug, Release, etc
1608     linkDirs += *d;
1609     linkDirs += "/$(Configuration)";
1610     linkDirs += sep;
1611     }
1612   linkDirs += "%(AdditionalLibraryDirectories)";
1613   linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs.c_str());
1614   linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
1615   linkOptions.AddFlag("Version", "");
1616   if(linkOptions.IsDebug() || flags.find("/debug") != flags.npos)
1617     {
1618     linkOptions.AddFlag("GenerateDebugInformation", "true");
1619     }
1620   else
1621     {
1622     linkOptions.AddFlag("GenerateDebugInformation", "false");
1623     }
1624   std::string targetName;
1625   std::string targetNameSO;
1626   std::string targetNameFull;
1627   std::string targetNameImport;
1628   std::string targetNamePDB;
1629   if(this->Target->GetType() == cmTarget::EXECUTABLE)
1630     {
1631     this->Target->GetExecutableNames(targetName, targetNameFull,
1632                                      targetNameImport, targetNamePDB,
1633                                      config.c_str());
1634     }
1635   else
1636     {
1637     this->Target->GetLibraryNames(targetName, targetNameSO, targetNameFull,
1638                                   targetNameImport, targetNamePDB,
1639                                   config.c_str());
1640     }
1641
1642   std::string pdb = this->Target->GetPDBDirectory(config.c_str());
1643   pdb += "/";
1644   pdb += targetNamePDB;
1645   std::string imLib = this->Target->GetDirectory(config.c_str(), true);
1646   imLib += "/";
1647   imLib += targetNameImport;
1648
1649   linkOptions.AddFlag("ImportLibrary", imLib.c_str());
1650   linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
1651   linkOptions.Parse(flags.c_str());
1652   if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
1653     {
1654     linkOptions.AddFlag("ModuleDefinitionFile",
1655                         this->GeneratorTarget->ModuleDefinitionFile.c_str());
1656     }
1657
1658   this->LinkOptions[config] = pOptions.release();
1659   return true;
1660 }
1661
1662 //----------------------------------------------------------------------------
1663 void
1664 cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
1665 {
1666   if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
1667      || this->Target->GetType() > cmTarget::MODULE_LIBRARY)
1668     {
1669     return;
1670     }
1671   Options& linkOptions = *(this->LinkOptions[config]);
1672   this->WriteString("<Link>\n", 2);
1673
1674   linkOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
1675   linkOptions.OutputFlagMap(*this->BuildFileStream, "      ");
1676
1677   this->WriteString("</Link>\n", 2);
1678   if(!this->GlobalGenerator->NeedLinkLibraryDependencies(*this->Target))
1679     {
1680     this->WriteString("<ProjectReference>\n", 2);
1681     this->WriteString(
1682       "  <LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 2);
1683     this->WriteString("</ProjectReference>\n", 2);
1684     }
1685 }
1686
1687 void cmVisualStudio10TargetGenerator::AddLibraries(
1688   cmComputeLinkInformation& cli,
1689   std::string& libstring)
1690 {
1691   typedef cmComputeLinkInformation::ItemVector ItemVector;
1692   ItemVector libs = cli.GetItems();
1693   const char* sep = ";";
1694   for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
1695     {
1696     if(l->IsPath)
1697       {
1698       std::string path = this->LocalGenerator->
1699         Convert(l->Value.c_str(),
1700                 cmLocalGenerator::START_OUTPUT,
1701                 cmLocalGenerator::UNCHANGED);
1702       this->ConvertToWindowsSlash(path);
1703       libstring += sep;
1704       libstring += path;
1705       }
1706     else
1707       {
1708       libstring += sep;
1709       libstring += l->Value;
1710       }
1711     }
1712 }
1713
1714
1715 void cmVisualStudio10TargetGenerator::
1716 WriteMidlOptions(std::string const& /*config*/,
1717                  std::vector<std::string> const & includes)
1718 {
1719   // This processes *any* of the .idl files specified in the project's file
1720   // list (and passed as the item metadata %(Filename) expressing the rule
1721   // input filename) into output files at the per-config *build* dir
1722   // ($(IntDir)) each.
1723   //
1724   // IOW, this MIDL section is intended to provide a fully generic syntax
1725   // content suitable for most cases (read: if you get errors, then it's quite
1726   // probable that the error is on your side of the .idl setup).
1727   //
1728   // Also, note that the marked-as-generated _i.c file in the Visual Studio
1729   // generator case needs to be referred to as $(IntDir)\foo_i.c at the
1730   // project's file list, otherwise the compiler-side processing won't pick it
1731   // up (for non-directory form, it ends up looking in project binary dir
1732   // only).  Perhaps there's something to be done to make this more automatic
1733   // on the CMake side?
1734   this->WriteString("<Midl>\n", 2);
1735   this->OutputIncludes(includes);
1736   this->WriteString("<OutputDirectory>$(IntDir)</OutputDirectory>\n", 3);
1737   this->WriteString("<HeaderFileName>%(Filename).h</HeaderFileName>\n", 3);
1738   this->WriteString(
1739     "<TypeLibraryName>%(Filename).tlb</TypeLibraryName>\n", 3);
1740   this->WriteString(
1741     "<InterfaceIdentifierFileName>"
1742     "%(Filename)_i.c</InterfaceIdentifierFileName>\n", 3);
1743   this->WriteString("<ProxyFileName>%(Filename)_p.c</ProxyFileName>\n",3);
1744   this->WriteString("</Midl>\n", 2);
1745 }
1746
1747
1748 void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
1749 {
1750   std::vector<std::string> *configs =
1751     static_cast<cmGlobalVisualStudio7Generator *>
1752     (this->GlobalGenerator)->GetConfigurations();
1753   for(std::vector<std::string>::iterator i = configs->begin();
1754       i != configs->end(); ++i)
1755     {
1756     std::vector<std::string> includes;
1757     this->LocalGenerator->GetIncludeDirectories(includes,
1758                                                 this->GeneratorTarget,
1759                                                 "C", i->c_str());
1760     this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1);
1761     *this->BuildFileStream << "\n";
1762     //    output cl compile flags <ClCompile></ClCompile>
1763     if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
1764       {
1765       this->WriteClOptions(*i, includes);
1766       //    output rc compile flags <ResourceCompile></ResourceCompile>
1767       this->WriteRCOptions(*i, includes);
1768       }
1769     //    output midl flags       <Midl></Midl>
1770     this->WriteMidlOptions(*i, includes);
1771     // write events
1772     this->WriteEvents(*i);
1773     //    output link flags       <Link></Link>
1774     this->WriteLinkOptions(*i);
1775     //    output lib flags       <Lib></Lib>
1776     this->WriteLibOptions(*i);
1777     this->WriteString("</ItemDefinitionGroup>\n", 1);
1778     }
1779 }
1780
1781 void
1782 cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
1783 {
1784   this->WriteEvent("PreLinkEvent",
1785                    this->Target->GetPreLinkCommands(), configName);
1786   this->WriteEvent("PreBuildEvent",
1787                    this->Target->GetPreBuildCommands(), configName);
1788   this->WriteEvent("PostBuildEvent",
1789                    this->Target->GetPostBuildCommands(), configName);
1790 }
1791
1792 void cmVisualStudio10TargetGenerator::WriteEvent(
1793   const char* name,
1794   std::vector<cmCustomCommand> & commands,
1795   std::string const& configName)
1796 {
1797   if(commands.size() == 0)
1798     {
1799     return;
1800     }
1801   this->WriteString("<", 2);
1802   (*this->BuildFileStream ) << name << ">\n";
1803   cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
1804   std::string script;
1805   const char* pre = "";
1806   std::string comment;
1807   for(std::vector<cmCustomCommand>::iterator i = commands.begin();
1808       i != commands.end(); ++i)
1809     {
1810     cmCustomCommand& command = *i;
1811     comment += pre;
1812     comment += lg->ConstructComment(command);
1813     script += pre;
1814     pre = "\n";
1815     script +=
1816       cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
1817     }
1818   comment = cmVS10EscapeComment(comment);
1819   this->WriteString("<Message>",3);
1820   (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
1821   this->WriteString("<Command>", 3);
1822   (*this->BuildFileStream ) << script;
1823   (*this->BuildFileStream ) << "</Command>" << "\n";
1824   this->WriteString("</", 2);
1825   (*this->BuildFileStream ) << name << ">\n";
1826 }
1827
1828
1829 void cmVisualStudio10TargetGenerator::WriteProjectReferences()
1830 {
1831   cmGlobalGenerator::TargetDependSet const& unordered
1832     = this->GlobalGenerator->GetTargetDirectDepends(*this->Target);
1833   typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet
1834     OrderedTargetDependSet;
1835   OrderedTargetDependSet depends(unordered);
1836   this->WriteString("<ItemGroup>\n", 1);
1837   for( OrderedTargetDependSet::const_iterator i = depends.begin();
1838        i != depends.end(); ++i)
1839     {
1840     cmTarget* dt = *i;
1841     // skip fortran targets as they can not be processed by MSBuild
1842     // the only reference will be in the .sln file
1843     if(static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
1844        ->TargetIsFortranOnly(*dt))
1845       {
1846       continue;
1847       }
1848     this->WriteString("<ProjectReference Include=\"", 2);
1849     cmMakefile* mf = dt->GetMakefile();
1850     std::string name = dt->GetName();
1851     std::string path;
1852     const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
1853     if(p)
1854       {
1855       path = p;
1856       }
1857     else
1858       {
1859       path =  mf->GetStartOutputDirectory();
1860       path += "/";
1861       path += dt->GetName();
1862       path += ".vcxproj";
1863       }
1864     (*this->BuildFileStream) << path << "\">\n";
1865     this->WriteString("<Project>", 3);
1866     (*this->BuildFileStream)
1867       << this->GlobalGenerator->GetGUID(name.c_str())
1868       << "</Project>\n";
1869     this->WriteString("</ProjectReference>\n", 2);
1870     }
1871   this->WriteString("</ItemGroup>\n", 1);
1872 }
1873
1874 bool cmVisualStudio10TargetGenerator::
1875   IsResxHeader(const std::string& headerFile)
1876 {
1877   std::set<std::string>::iterator it =
1878       this->GeneratorTarget->ExpectedResxHeaders.find(headerFile);
1879
1880   return it != this->GeneratorTarget->ExpectedResxHeaders.end();
1881 }