1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
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 "cmGlobalVisualStudio71Generator.h"
14 #include "cmLocalVisualStudio7Generator.h"
15 #include "cmMakefile.h"
18 //----------------------------------------------------------------------------
19 cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(
20 const char* platformName) : cmGlobalVisualStudio7Generator(platformName)
22 this->FindMakeProgramFile = "CMakeVS71FindMake.cmake";
23 this->ProjectConfigurationSectionName = "ProjectConfiguration";
26 //----------------------------------------------------------------------------
27 ///! Create a local generator appropriate to this Global Generator
28 cmLocalGenerator *cmGlobalVisualStudio71Generator::CreateLocalGenerator()
30 cmLocalVisualStudio7Generator *lg =
31 new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS71);
32 lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
33 lg->SetGlobalGenerator(this);
37 //----------------------------------------------------------------------------
38 std::string cmGlobalVisualStudio71Generator::GetUserMacrosDirectory()
40 // Macros not supported on Visual Studio 7.1 and earlier because
41 // they do not appear to work *during* a build when called by an
48 // The COM result from calling a Visual Studio macro with 7.1 indicates
49 // that the call succeeds, but the macro does not appear to execute...
51 // So, I am leaving this code here to show how to do it, but have not
52 // yet figured out what the issue is in terms of why the macro does not
53 // appear to execute...
58 // base begins with the VisualStudioProjectsLocation reg value...
59 if (cmSystemTools::ReadRegistryValue(
60 "HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\7.1;"
61 "VisualStudioProjectsLocation",
64 cmSystemTools::ConvertToUnixSlashes(base);
67 path = base + "/VSMacros71";
70 // path is (correctly) still empty if we did not read the base value from
76 //----------------------------------------------------------------------------
77 std::string cmGlobalVisualStudio71Generator::GetUserMacrosRegKeyBase()
79 // Macros not supported on Visual Studio 7.1 and earlier because
80 // they do not appear to work *during* a build when called by an
86 return "Software\\Microsoft\\VisualStudio\\7.1\\vsmacros";
90 //----------------------------------------------------------------------------
91 void cmGlobalVisualStudio71Generator
92 ::WriteSLNFile(std::ostream& fout,
93 cmLocalGenerator* root,
94 std::vector<cmLocalGenerator*>& generators)
96 // Write out the header for a SLN file
97 this->WriteSLNHeader(fout);
99 // Collect all targets under this root generator and the transitive
100 // closure of their dependencies.
101 TargetDependSet projectTargets;
102 TargetDependSet originalTargets;
103 this->GetTargetSets(projectTargets, originalTargets, root, generators);
104 OrderedTargetDependSet orderedProjectTargets(projectTargets);
106 this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
108 bool useFolderProperty = this->UseFolderProperty();
109 if (useFolderProperty)
111 this->WriteFolders(fout);
114 // Write out the configurations information for the solution
116 // Write out the configurations for the solution
117 this->WriteSolutionConfigurations(fout);
118 fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
119 << ") = postSolution\n";
120 // Write out the configurations for all the targets in the project
121 this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
122 fout << "\tEndGlobalSection\n";
124 if (useFolderProperty)
126 // Write out project folders
127 fout << "\tGlobalSection(NestedProjects) = preSolution\n";
128 this->WriteFoldersContent(fout);
129 fout << "\tEndGlobalSection\n";
132 // Write out global sections
133 this->WriteSLNGlobalSections(fout, root);
135 // Write the footer for the SLN file
136 this->WriteSLNFooter(fout);
139 //----------------------------------------------------------------------------
141 cmGlobalVisualStudio71Generator
142 ::WriteSolutionConfigurations(std::ostream& fout)
144 fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
145 for(std::vector<std::string>::iterator i = this->Configurations.begin();
146 i != this->Configurations.end(); ++i)
148 fout << "\t\t" << *i << " = " << *i << "\n";
150 fout << "\tEndGlobalSection\n";
153 //----------------------------------------------------------------------------
154 // Write a dsp file into the SLN file,
155 // Note, that dependencies from executables to
156 // the libraries it uses are also done here
158 cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
163 // check to see if this is a fortran build
164 const char* ext = ".vcproj";
165 const char* project =
166 "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
167 if(this->TargetIsFortranOnly(t))
170 project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
172 const char* targetExt = t.GetProperty("GENERATOR_FILE_NAME_EXT");
178 std::string guid = this->GetGUID(dspname);
180 << dspname << "\", \""
181 << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
182 << dspname << ext << "\", \"{" << guid << "}\"\n";
183 fout << "\tProjectSection(ProjectDependencies) = postProject\n";
184 this->WriteProjectDepends(fout, dspname, dir, t);
185 fout << "\tEndProjectSection\n";
187 fout <<"EndProject\n";
189 UtilityDependsMap::iterator ui = this->UtilityDepends.find(&t);
190 if(ui != this->UtilityDepends.end())
192 const char* uname = ui->second.c_str();
193 fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
195 << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
196 << uname << ".vcproj" << "\", \"{"
197 << this->GetGUID(uname) << "}\"\n"
198 << "\tProjectSection(ProjectDependencies) = postProject\n"
199 << "\t\t{" << guid << "} = {" << guid << "}\n"
200 << "\tEndProjectSection\n"
205 //----------------------------------------------------------------------------
206 // Write a dsp file into the SLN file,
207 // Note, that dependencies from executables to
208 // the libraries it uses are also done here
210 cmGlobalVisualStudio71Generator
211 ::WriteProjectDepends(std::ostream& fout,
213 const char*, cmTarget& target)
215 VSDependSet const& depends = this->VSTargetDepends[&target];
216 for(VSDependSet::const_iterator di = depends.begin();
217 di != depends.end(); ++di)
219 const char* name = di->c_str();
220 std::string guid = this->GetGUID(name);
223 std::string m = "Target: ";
224 m += target.GetName();
225 m += " depends on unknown target: ";
227 cmSystemTools::Error(m.c_str());
229 fout << "\t\t{" << guid << "} = {" << guid << "}\n";
233 //----------------------------------------------------------------------------
234 // Write a dsp file into the SLN file, Note, that dependencies from
235 // executables to the libraries it uses are also done here
236 void cmGlobalVisualStudio71Generator
237 ::WriteExternalProject(std::ostream& fout,
239 const char* location,
240 const char* typeGuid,
241 const std::set<cmStdString>& depends)
243 fout << "Project(\"{"
244 << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942")
247 << this->ConvertToSolutionPath(location) << "\", \"{"
248 << this->GetGUID(name)
251 // write out the dependencies here VS 7.1 includes dependencies with the
252 // project instead of in the global section
255 fout << "\tProjectSection(ProjectDependencies) = postProject\n";
256 std::set<cmStdString>::const_iterator it;
257 for(it = depends.begin(); it != depends.end(); ++it)
262 << this->GetGUID(it->c_str())
264 << this->GetGUID(it->c_str())
268 fout << "\tEndProjectSection\n";
271 fout << "EndProject\n";
276 //----------------------------------------------------------------------------
277 // Write a dsp file into the SLN file, Note, that dependencies from
278 // executables to the libraries it uses are also done here
279 void cmGlobalVisualStudio71Generator
280 ::WriteProjectConfigurations(
281 std::ostream& fout, const char* name, cmTarget::TargetType,
282 const std::set<std::string>& configsPartOfDefaultBuild,
283 const char* platformMapping)
285 const char* platformName =
286 platformMapping ? platformMapping : this->GetPlatformName();
287 std::string guid = this->GetGUID(name);
288 for(std::vector<std::string>::iterator i = this->Configurations.begin();
289 i != this->Configurations.end(); ++i)
291 fout << "\t\t{" << guid << "}." << *i
292 << ".ActiveCfg = " << *i << "|" << platformName << std::endl;
293 std::set<std::string>::const_iterator
294 ci = configsPartOfDefaultBuild.find(*i);
295 if(!(ci == configsPartOfDefaultBuild.end()))
297 fout << "\t\t{" << guid << "}." << *i
298 << ".Build.0 = " << *i << "|" << platformName << std::endl;
303 //----------------------------------------------------------------------------
304 // ouput standard header for dsw file
305 void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout)
307 fout << "Microsoft Visual Studio Solution File, Format Version 8.00\n";
310 //----------------------------------------------------------------------------
311 void cmGlobalVisualStudio71Generator
312 ::GetDocumentation(cmDocumentationEntry& entry)
314 entry.Name = cmGlobalVisualStudio71Generator::GetActualName();
315 entry.Brief = "Generates Visual Studio .NET 2003 project files.";