1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmGlobalVisualStudio71Generator.h"
8 #include "cmGeneratorTarget.h"
9 #include "cmGlobalGenerator.h"
10 #include "cmGlobalVisualStudioGenerator.h"
11 #include "cmListFileCache.h"
12 #include "cmLocalGenerator.h"
13 #include "cmMakefile.h"
14 #include "cmStringAlgorithms.h"
15 #include "cmSystemTools.h"
19 cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(
20 cmake* cm, const std::string& platformName)
21 : cmGlobalVisualStudio7Generator(cm, platformName)
23 this->ProjectConfigurationSectionName = "ProjectConfiguration";
26 void cmGlobalVisualStudio71Generator::WriteSLNFile(
27 std::ostream& fout, cmLocalGenerator* root,
28 std::vector<cmLocalGenerator*>& generators)
30 std::vector<std::string> configs =
31 root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
33 // Write out the header for a SLN file
34 this->WriteSLNHeader(fout);
36 // Collect all targets under this root generator and the transitive
37 // closure of their dependencies.
38 TargetDependSet projectTargets;
39 TargetDependSet originalTargets;
40 this->GetTargetSets(projectTargets, originalTargets, root, generators);
41 OrderedTargetDependSet orderedProjectTargets(
42 projectTargets, this->GetStartupProjectName(root));
44 // Generate the targets specification to a string. We will put this in
45 // the actual .sln file later. As a side effect, this method also
46 // populates the set of folders.
47 std::ostringstream targetsSlnString;
48 this->WriteTargetsToSolution(targetsSlnString, root, orderedProjectTargets);
50 // Generate folder specification.
51 bool useFolderProperty = this->UseFolderProperty();
52 if (useFolderProperty) {
53 this->WriteFolders(fout);
56 // Now write the actual target specification content.
57 fout << targetsSlnString.str();
59 // Write out the configurations information for the solution
61 // Write out the configurations for the solution
62 this->WriteSolutionConfigurations(fout, configs);
63 fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
64 << ") = postSolution\n";
65 // Write out the configurations for all the targets in the project
66 this->WriteTargetConfigurations(fout, configs, orderedProjectTargets);
67 fout << "\tEndGlobalSection\n";
69 if (useFolderProperty) {
70 // Write out project folders
71 fout << "\tGlobalSection(NestedProjects) = preSolution\n";
72 this->WriteFoldersContent(fout);
73 fout << "\tEndGlobalSection\n";
76 // Write out global sections
77 this->WriteSLNGlobalSections(fout, root);
79 // Write the footer for the SLN file
80 this->WriteSLNFooter(fout);
83 void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations(
84 std::ostream& fout, std::vector<std::string> const& configs)
86 fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
87 for (std::string const& i : configs) {
88 fout << "\t\t" << i << " = " << i << "\n";
90 fout << "\tEndGlobalSection\n";
93 // Write a dsp file into the SLN file,
94 // Note, that dependencies from executables to
95 // the libraries it uses are also done here
96 void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
97 const std::string& dspname,
98 const std::string& dir,
99 cmGeneratorTarget const* t)
101 // check to see if this is a fortran build
102 std::string ext = ".vcproj";
103 const char* project =
104 "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
105 if (this->TargetIsFortranOnly(t)) {
107 project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
109 if (t->IsCSharpOnly()) {
111 project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
113 cmValue targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
118 std::string guid = this->GetGUID(dspname);
119 fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir)
120 << (!dir.empty() ? "\\" : "") << dspname << ext << "\", \"{" << guid
122 fout << "\tProjectSection(ProjectDependencies) = postProject\n";
123 this->WriteProjectDepends(fout, dspname, dir, t);
124 fout << "\tEndProjectSection\n";
126 fout << "EndProject\n";
128 UtilityDependsMap::iterator ui = this->UtilityDepends.find(t);
129 if (ui != this->UtilityDepends.end()) {
130 const char* uname = ui->second.c_str();
131 /* clang-format off */
132 fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
134 << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
135 << uname << ".vcproj" << "\", \"{"
136 << this->GetGUID(uname) << "}\"\n"
137 << "\tProjectSection(ProjectDependencies) = postProject\n"
138 << "\t\t{" << guid << "} = {" << guid << "}\n"
139 << "\tEndProjectSection\n"
141 /* clang-format on */
145 // Write a dsp file into the SLN file,
146 // Note, that dependencies from executables to
147 // the libraries it uses are also done here
148 void cmGlobalVisualStudio71Generator::WriteProjectDepends(
149 std::ostream& fout, const std::string&, const std::string&,
150 cmGeneratorTarget const* target)
152 VSDependSet const& depends = this->VSTargetDepends[target];
153 for (std::string const& name : depends) {
154 std::string guid = this->GetGUID(name);
156 std::string m = cmStrCat("Target: ", target->GetName(),
157 " depends on unknown target: ", name);
158 cmSystemTools::Error(m);
160 fout << "\t\t{" << guid << "} = {" << guid << "}\n";
164 // Write a dsp file into the SLN file, Note, that dependencies from
165 // executables to the libraries it uses are also done here
166 void cmGlobalVisualStudio71Generator::WriteExternalProject(
167 std::ostream& fout, const std::string& name, const std::string& location,
168 cmValue typeGuid, const std::set<BT<std::pair<std::string, bool>>>& depends)
170 fout << "Project(\"{"
171 << (typeGuid ? typeGuid
172 : std::string(this->ExternalProjectType(location)))
173 << "}\") = \"" << name << "\", \""
174 << this->ConvertToSolutionPath(location) << "\", \"{"
175 << this->GetGUID(name) << "}\"\n";
177 // write out the dependencies here VS 7.1 includes dependencies with the
178 // project instead of in the global section
179 if (!depends.empty()) {
180 fout << "\tProjectSection(ProjectDependencies) = postProject\n";
181 for (BT<std::pair<std::string, bool>> const& it : depends) {
182 std::string const& dep = it.Value.first;
183 if (this->IsDepInSolution(dep)) {
184 fout << "\t\t{" << this->GetGUID(dep) << "} = {" << this->GetGUID(dep)
188 fout << "\tEndProjectSection\n";
191 fout << "EndProject\n";
194 // Write a dsp file into the SLN file, Note, that dependencies from
195 // executables to the libraries it uses are also done here
196 void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
197 std::ostream& fout, const std::string& name, cmGeneratorTarget const& target,
198 std::vector<std::string> const& configs,
199 const std::set<std::string>& configsPartOfDefaultBuild,
200 std::string const& platformMapping)
202 const std::string& platformName =
203 !platformMapping.empty() ? platformMapping : this->GetPlatformName();
204 std::string guid = this->GetGUID(name);
205 for (std::string const& i : configs) {
206 std::vector<std::string> mapConfig;
207 const char* dstConfig = i.c_str();
208 if (target.GetProperty("EXTERNAL_MSPROJECT")) {
209 if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
210 cmSystemTools::UpperCase(i))) {
211 cmExpandList(*m, mapConfig);
212 if (!mapConfig.empty()) {
213 dstConfig = mapConfig[0].c_str();
217 fout << "\t\t{" << guid << "}." << i << ".ActiveCfg = " << dstConfig << "|"
218 << platformName << std::endl;
219 std::set<std::string>::const_iterator ci =
220 configsPartOfDefaultBuild.find(i);
221 if (!(ci == configsPartOfDefaultBuild.end())) {
222 fout << "\t\t{" << guid << "}." << i << ".Build.0 = " << dstConfig << "|"
223 << platformName << std::endl;