1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmGlobalVisualStudio71Generator.cxx,v $
6 Date: $Date: 2007-12-23 18:13:44 $
7 Version: $Revision: 1.45 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "windows.h" // this must be first to define GetCurrentDirectory
18 #include "cmGlobalVisualStudio71Generator.h"
19 #include "cmLocalVisualStudio7Generator.h"
20 #include "cmMakefile.h"
25 cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator()
27 this->FindMakeProgramFile
= "CMakeVS71FindMake.cmake";
28 this->ProjectConfigurationSectionName
= "ProjectConfiguration";
33 ///! Create a local generator appropriate to this Global Generator
34 cmLocalGenerator
*cmGlobalVisualStudio71Generator::CreateLocalGenerator()
36 cmLocalVisualStudio7Generator
*lg
= new cmLocalVisualStudio7Generator
;
38 lg
->SetExtraFlagTable(this->GetExtraFlagTableVS7());
39 lg
->SetGlobalGenerator(this);
43 void cmGlobalVisualStudio71Generator::AddPlatformDefinitions(cmMakefile
* mf
)
45 mf
->AddDefinition("MSVC71", "1");
48 // Write a SLN file to the stream
49 void cmGlobalVisualStudio71Generator
50 ::WriteSLNFile(std::ostream
& fout
,
51 cmLocalGenerator
* root
,
52 std::vector
<cmLocalGenerator
*>& generators
)
54 // Write out the header for a SLN file
55 this->WriteSLNHeader(fout
);
57 // Get the start directory with the trailing slash
58 std::string rootdir
= root
->GetMakefile()->GetStartOutputDirectory();
60 bool doneAllBuild
= false;
61 bool doneCheckBuild
= false;
62 bool doneRunTests
= false;
63 bool doneInstall
= false;
64 bool doneEditCache
= false;
65 bool doneRebuildCache
= false;
66 bool donePackage
= false;
68 // For each cmMakefile, create a VCProj for it, and
69 // add it to this SLN file
71 for(i
= 0; i
< generators
.size(); ++i
)
73 if(this->IsExcluded(root
, generators
[i
]))
77 cmMakefile
* mf
= generators
[i
]->GetMakefile();
79 // Get the source directory from the makefile
80 std::string dir
= mf
->GetStartOutputDirectory();
81 // remove the home directory and / from the source directory
82 // this gives a relative path
83 cmSystemTools::ReplaceString(dir
, rootdir
.c_str(), "");
85 // Get the list of create dsp files names from the cmVCProjWriter, more
86 // than one dsp could have been created per input CMakeLists.txt file
88 cmTargets
&tgts
= generators
[i
]->GetMakefile()->GetTargets();
89 cmTargets::iterator l
= tgts
.begin();
90 for(; l
!= tgts
.end(); ++l
)
92 // special handling for the current makefile
93 if(mf
== generators
[0]->GetMakefile())
95 dir
= "."; // no subdirectory for project generated
96 // if this is the special ALL_BUILD utility, then
97 // make it depend on every other non UTILITY project.
98 // This is done by adding the names to the GetUtilities
99 // vector on the makefile
100 if(l
->first
== "ALL_BUILD" && !doneAllBuild
)
103 for(j
= 0; j
< generators
.size(); ++j
)
105 cmTargets
&atgts
= generators
[j
]->GetMakefile()->GetTargets();
106 for(cmTargets::iterator al
= atgts
.begin();
107 al
!= atgts
.end(); ++al
)
109 if (!al
->second
.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
111 if (al
->second
.GetType() == cmTarget::UTILITY
||
112 al
->second
.GetType() == cmTarget::GLOBAL_TARGET
)
114 l
->second
.AddUtility(al
->first
.c_str());
118 l
->second
.AddLinkLibrary(al
->first
,cmTarget::GENERAL
);
125 // Write the project into the SLN file
126 if (strncmp(l
->first
.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
128 cmCustomCommand cc
= l
->second
.GetPostBuildCommands()[0];
129 const cmCustomCommandLines
& cmds
= cc
.GetCommandLines();
130 std::string project
= cmds
[0][0];
131 std::string location
= cmds
[0][1];
132 this->WriteExternalProject(fout
, project
.c_str(),
133 location
.c_str(), cc
.GetDepends());
138 if(l
->first
== "ALL_BUILD" )
149 if(l
->first
== CMAKE_CHECK_BUILD_SYSTEM_TARGET
)
157 doneCheckBuild
= true;
160 if(l
->first
== "INSTALL")
171 if(l
->first
== "RUN_TESTS")
182 if(l
->first
== "EDIT_CACHE")
190 doneEditCache
= true;
193 if(l
->first
== "REBUILD_CACHE")
201 doneRebuildCache
= true;
204 if(l
->first
== "PACKAGE")
217 const char *dspname
=
218 l
->second
.GetProperty("GENERATOR_FILE_NAME");
221 this->WriteProject(fout
, dspname
, dir
.c_str(),l
->second
);
228 this->WriteSolutionConfigurations(fout
);
229 fout
<< "\tGlobalSection(" << this->ProjectConfigurationSectionName
230 << ") = postSolution\n";
231 // loop over again and compute the depends
232 for(i
= 0; i
< generators
.size(); ++i
)
234 cmMakefile
* mf
= generators
[i
]->GetMakefile();
235 cmLocalVisualStudio7Generator
* pg
=
236 static_cast<cmLocalVisualStudio7Generator
*>(generators
[i
]);
237 // Get the list of create dsp files names from the cmVCProjWriter, more
238 // than one dsp could have been created per input CMakeLists.txt file
240 cmTargets
&tgts
= pg
->GetMakefile()->GetTargets();
241 cmTargets::iterator l
= tgts
.begin();
242 std::string dir
= mf
->GetStartDirectory();
243 for(; l
!= tgts
.end(); ++l
)
245 if (strncmp(l
->first
.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
247 cmCustomCommand cc
= l
->second
.GetPostBuildCommands()[0];
248 const cmCustomCommandLines
& cmds
= cc
.GetCommandLines();
249 std::string project
= cmds
[0][0];
250 this->WriteProjectConfigurations(fout
, project
.c_str(),
255 bool partOfDefaultBuild
= this->IsPartOfDefaultBuild(
256 root
->GetMakefile()->GetProjectName(),
258 const char *dspname
=
259 l
->second
.GetProperty("GENERATOR_FILE_NAME");
262 this->WriteProjectConfigurations(fout
, dspname
,
268 fout
<< "\tEndGlobalSection\n";
270 // Write the footer for the SLN file
271 this->WriteSLNFooter(fout
);
276 cmGlobalVisualStudio71Generator
277 ::WriteSolutionConfigurations(std::ostream
& fout
)
279 fout
<< "\tGlobalSection(SolutionConfiguration) = preSolution\n";
280 for(std::vector
<std::string
>::iterator i
= this->Configurations
.begin();
281 i
!= this->Configurations
.end(); ++i
)
283 fout
<< "\t\t" << *i
<< " = " << *i
<< "\n";
285 fout
<< "\tEndGlobalSection\n";
288 // Write a dsp file into the SLN file,
289 // Note, that dependencies from executables to
290 // the libraries it uses are also done here
292 cmGlobalVisualStudio71Generator::WriteProject(std::ostream
& fout
,
297 fout
<< "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
298 << dspname
<< "\", \""
299 << this->ConvertToSolutionPath(dir
)
300 << "\\" << dspname
<< ".vcproj\", \"{"
301 << this->GetGUID(dspname
) << "}\"\n";
302 fout
<< "\tProjectSection(ProjectDependencies) = postProject\n";
303 this->WriteProjectDepends(fout
, dspname
, dir
, t
);
304 fout
<< "\tEndProjectSection\n";
306 fout
<<"EndProject\n";
311 // Write a dsp file into the SLN file,
312 // Note, that dependencies from executables to
313 // the libraries it uses are also done here
315 cmGlobalVisualStudio71Generator
316 ::WriteProjectDepends(std::ostream
& fout
,
318 const char*, cmTarget
& target
)
321 // Create inter-target dependencies in the solution file. For VS
322 // 7.1 and below we cannot let static libraries depend directly on
323 // targets to which they "link" because the librarian tool will copy
324 // the targets into the static library. See
325 // cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget for a
326 // work-around. VS 8 and above do not have this problem.
327 if (!this->VSLinksDependencies() ||
328 target
.GetType() != cmTarget::STATIC_LIBRARY
);
330 if (target
.GetType() != cmTarget::STATIC_LIBRARY
)
333 cmTarget::LinkLibraryVectorType::const_iterator j
, jend
;
334 j
= target
.GetLinkLibraries().begin();
335 jend
= target
.GetLinkLibraries().end();
338 if(j
->first
!= dspname
)
340 // is the library part of this SLN ? If so add dependency
341 if(this->FindTarget(this->CurrentProject
.c_str(),
342 j
->first
.c_str(), false))
344 fout
<< "\t\t{" << this->GetGUID(j
->first
.c_str()) << "} = {"
345 << this->GetGUID(j
->first
.c_str()) << "}\n";
351 std::set
<cmStdString
>::const_iterator i
, end
;
352 // write utility dependencies.
353 i
= target
.GetUtilities().begin();
354 end
= target
.GetUtilities().end();
359 std::string name
= this->GetUtilityForTarget(target
, i
->c_str());
360 std::string guid
= this->GetGUID(name
.c_str());
363 std::string m
= "Target: ";
364 m
+= target
.GetName();
365 m
+= " depends on unknown target: ";
367 cmSystemTools::Error(m
.c_str());
370 fout
<< "\t\t{" << guid
<< "} = {" << guid
<< "}\n";
375 // Write a dsp file into the SLN file, Note, that dependencies from
376 // executables to the libraries it uses are also done here
377 void cmGlobalVisualStudio71Generator
378 ::WriteExternalProject(std::ostream
& fout
,
380 const char* location
,
381 const std::vector
<std::string
>& depends
)
383 fout
<< "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
385 << this->ConvertToSolutionPath(location
) << "\", \"{"
386 << this->GetGUID(name
)
389 // write out the dependencies here VS 7.1 includes dependencies with the
390 // project instead of in the global section
393 fout
<< "\tProjectSection(ProjectDependencies) = postProject\n";
394 std::vector
<std::string
>::const_iterator it
;
395 for(it
= depends
.begin(); it
!= depends
.end(); ++it
)
400 << this->GetGUID(it
->c_str())
402 << this->GetGUID(it
->c_str())
406 fout
<< "\tEndProjectSection\n";
409 fout
<< "EndProject\n";
415 // Write a dsp file into the SLN file, Note, that dependencies from
416 // executables to the libraries it uses are also done here
417 void cmGlobalVisualStudio71Generator
418 ::WriteProjectConfigurations(std::ostream
& fout
, const char* name
,
419 bool partOfDefaultBuild
)
421 std::string guid
= this->GetGUID(name
);
422 for(std::vector
<std::string
>::iterator i
= this->Configurations
.begin();
423 i
!= this->Configurations
.end(); ++i
)
425 fout
<< "\t\t{" << guid
<< "}." << *i
426 << ".ActiveCfg = " << *i
<< "|Win32\n";
427 if(partOfDefaultBuild
)
429 fout
<< "\t\t{" << guid
<< "}." << *i
430 << ".Build.0 = " << *i
<< "|Win32\n";
438 // Standard end of dsw file
439 void cmGlobalVisualStudio71Generator::WriteSLNFooter(std::ostream
& fout
)
441 fout
<< "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
442 << "\tEndGlobalSection\n"
443 << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
444 << "\tEndGlobalSection\n"
449 // ouput standard header for dsw file
450 void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream
& fout
)
452 fout
<< "Microsoft Visual Studio Solution File, Format Version 8.00\n";
455 //----------------------------------------------------------------------------
456 void cmGlobalVisualStudio71Generator
457 ::GetDocumentation(cmDocumentationEntry
& entry
) const
459 entry
.Name
= this->GetName();
460 entry
.Brief
= "Generates Visual Studio .NET 2003 project files.";