resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGlobalVisualStudio71Generator.cxx
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"
4
5 #include <map>
6 #include <sstream>
7
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"
16
17 class cmake;
18
19 cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(
20   cmake* cm, const std::string& platformName)
21   : cmGlobalVisualStudio7Generator(cm, platformName)
22 {
23   this->ProjectConfigurationSectionName = "ProjectConfiguration";
24 }
25
26 void cmGlobalVisualStudio71Generator::WriteSLNFile(
27   std::ostream& fout, cmLocalGenerator* root,
28   std::vector<cmLocalGenerator*>& generators)
29 {
30   std::vector<std::string> configs =
31     root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
32
33   // Write out the header for a SLN file
34   this->WriteSLNHeader(fout);
35
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));
43
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);
49
50   // Generate folder specification.
51   bool useFolderProperty = this->UseFolderProperty();
52   if (useFolderProperty) {
53     this->WriteFolders(fout);
54   }
55
56   // Now write the actual target specification content.
57   fout << targetsSlnString.str();
58
59   // Write out the configurations information for the solution
60   fout << "Global\n";
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";
68
69   if (useFolderProperty) {
70     // Write out project folders
71     fout << "\tGlobalSection(NestedProjects) = preSolution\n";
72     this->WriteFoldersContent(fout);
73     fout << "\tEndGlobalSection\n";
74   }
75
76   // Write out global sections
77   this->WriteSLNGlobalSections(fout, root);
78
79   // Write the footer for the SLN file
80   this->WriteSLNFooter(fout);
81 }
82
83 void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations(
84   std::ostream& fout, std::vector<std::string> const& configs)
85 {
86   fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
87   for (std::string const& i : configs) {
88     fout << "\t\t" << i << " = " << i << "\n";
89   }
90   fout << "\tEndGlobalSection\n";
91 }
92
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)
100 {
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)) {
106     ext = ".vfproj";
107     project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
108   }
109   if (t->IsCSharpOnly()) {
110     ext = ".csproj";
111     project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
112   }
113   cmValue targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
114   if (targetExt) {
115     ext = *targetExt;
116   }
117
118   std::string guid = this->GetGUID(dspname);
119   fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir)
120        << (!dir.empty() ? "\\" : "") << dspname << ext << "\", \"{" << guid
121        << "}\"\n";
122   fout << "\tProjectSection(ProjectDependencies) = postProject\n";
123   this->WriteProjectDepends(fout, dspname, dir, t);
124   fout << "\tEndProjectSection\n";
125
126   fout << "EndProject\n";
127
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}\") = \""
133          << uname << "\", \""
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"
140          << "EndProject\n";
141     /* clang-format on */
142   }
143 }
144
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)
151 {
152   VSDependSet const& depends = this->VSTargetDepends[target];
153   for (std::string const& name : depends) {
154     std::string guid = this->GetGUID(name);
155     if (guid.empty()) {
156       std::string m = cmStrCat("Target: ", target->GetName(),
157                                " depends on unknown target: ", name);
158       cmSystemTools::Error(m);
159     }
160     fout << "\t\t{" << guid << "} = {" << guid << "}\n";
161   }
162 }
163
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)
169 {
170   fout << "Project(\"{"
171        << (typeGuid ? typeGuid
172                     : std::string(this->ExternalProjectType(location)))
173        << "}\") = \"" << name << "\", \""
174        << this->ConvertToSolutionPath(location) << "\", \"{"
175        << this->GetGUID(name) << "}\"\n";
176
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)
185              << "}\n";
186       }
187     }
188     fout << "\tEndProjectSection\n";
189   }
190
191   fout << "EndProject\n";
192 }
193
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)
201 {
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();
214         }
215       }
216     }
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;
224     }
225   }
226 }