resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGlobalVisualStudio12Generator.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 "cmGlobalVisualStudio12Generator.h"
4
5 #include <cstring>
6 #include <sstream>
7 #include <vector>
8
9 #include "cmDocumentationEntry.h"
10 #include "cmGlobalGenerator.h"
11 #include "cmGlobalGeneratorFactory.h"
12 #include "cmGlobalVisualStudioGenerator.h"
13 #include "cmMakefile.h"
14 #include "cmMessageType.h"
15 #include "cmStringAlgorithms.h"
16 #include "cmSystemTools.h"
17
18 static const char vs12generatorName[] = "Visual Studio 12 2013";
19
20 // Map generator name without year to name with year.
21 static const char* cmVS12GenName(const std::string& name, std::string& genName)
22 {
23   if (strncmp(name.c_str(), vs12generatorName,
24               sizeof(vs12generatorName) - 6) != 0) {
25     return 0;
26   }
27   const char* p = name.c_str() + sizeof(vs12generatorName) - 6;
28   if (cmHasLiteralPrefix(p, " 2013")) {
29     p += 5;
30   }
31   genName = std::string(vs12generatorName) + p;
32   return p;
33 }
34
35 class cmGlobalVisualStudio12Generator::Factory
36   : public cmGlobalGeneratorFactory
37 {
38 public:
39   std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
40     const std::string& name, bool allowArch, cmake* cm) const override
41   {
42     std::string genName;
43     const char* p = cmVS12GenName(name, genName);
44     if (!p) {
45       return std::unique_ptr<cmGlobalGenerator>();
46     }
47     if (!*p) {
48       return std::unique_ptr<cmGlobalGenerator>(
49         new cmGlobalVisualStudio12Generator(cm, genName, ""));
50     }
51     if (!allowArch || *p++ != ' ') {
52       return std::unique_ptr<cmGlobalGenerator>();
53     }
54     if (strcmp(p, "Win64") == 0) {
55       return std::unique_ptr<cmGlobalGenerator>(
56         new cmGlobalVisualStudio12Generator(cm, genName, "x64"));
57     }
58     if (strcmp(p, "ARM") == 0) {
59       return std::unique_ptr<cmGlobalGenerator>(
60         new cmGlobalVisualStudio12Generator(cm, genName, "ARM"));
61     }
62     return std::unique_ptr<cmGlobalGenerator>();
63   }
64
65   void GetDocumentation(cmDocumentationEntry& entry) const override
66   {
67     entry.Name = std::string(vs12generatorName) + " [arch]";
68     entry.Brief = "Generates Visual Studio 2013 project files.  "
69                   "Optional [arch] can be \"Win64\" or \"ARM\".";
70   }
71
72   std::vector<std::string> GetGeneratorNames() const override
73   {
74     std::vector<std::string> names;
75     names.push_back(vs12generatorName);
76     return names;
77   }
78
79   std::vector<std::string> GetGeneratorNamesWithPlatform() const override
80   {
81     std::vector<std::string> names;
82     names.push_back(vs12generatorName + std::string(" ARM"));
83     names.push_back(vs12generatorName + std::string(" Win64"));
84     return names;
85   }
86
87   bool SupportsToolset() const override { return true; }
88   bool SupportsPlatform() const override { return true; }
89
90   std::vector<std::string> GetKnownPlatforms() const override
91   {
92     std::vector<std::string> platforms;
93     platforms.emplace_back("x64");
94     platforms.emplace_back("Win32");
95     platforms.emplace_back("ARM");
96     return platforms;
97   }
98
99   std::string GetDefaultPlatformName() const override { return "Win32"; }
100 };
101
102 std::unique_ptr<cmGlobalGeneratorFactory>
103 cmGlobalVisualStudio12Generator::NewFactory()
104 {
105   return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
106 }
107
108 cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
109   cmake* cm, const std::string& name,
110   std::string const& platformInGeneratorName)
111   : cmGlobalVisualStudio11Generator(cm, name, platformInGeneratorName)
112 {
113   std::string vc12Express;
114   this->ExpressEdition = cmSystemTools::ReadRegistryValue(
115     "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\12.0\\Setup\\VC;"
116     "ProductDir",
117     vc12Express, cmSystemTools::KeyWOW64_32);
118   this->DefaultPlatformToolset = "v120";
119   this->DefaultCLFlagTableName = "v12";
120   this->DefaultCSharpFlagTableName = "v12";
121   this->DefaultLibFlagTableName = "v12";
122   this->DefaultLinkFlagTableName = "v12";
123   this->DefaultMasmFlagTableName = "v12";
124   this->DefaultRCFlagTableName = "v12";
125   this->Version = VSVersion::VS12;
126 }
127
128 bool cmGlobalVisualStudio12Generator::MatchesGeneratorName(
129   const std::string& name) const
130 {
131   std::string genName;
132   if (cmVS12GenName(name, genName)) {
133     return genName == this->GetName();
134   }
135   return false;
136 }
137
138 bool cmGlobalVisualStudio12Generator::ProcessGeneratorToolsetField(
139   std::string const& key, std::string const& value)
140 {
141   if (key == "host" &&
142       (value == "x64" || value == "x86" || value == "ARM64")) {
143     this->GeneratorToolsetHostArchitecture = value;
144     return true;
145   }
146   return this->cmGlobalVisualStudio11Generator::ProcessGeneratorToolsetField(
147     key, value);
148 }
149
150 bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
151 {
152   if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
153     std::ostringstream e;
154     if (this->DefaultPlatformToolset.empty()) {
155       e << this->GetName()
156         << " supports Windows Phone '8.0' and '8.1', but "
157            "not '"
158         << this->SystemVersion << "'.  Check CMAKE_SYSTEM_VERSION.";
159     } else {
160       e << "A Windows Phone component with CMake requires both the Windows "
161         << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
162         << "' SDK. Please make sure that you have both installed";
163     }
164     mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
165     return false;
166   }
167   return true;
168 }
169
170 bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf)
171 {
172   if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
173     std::ostringstream e;
174     if (this->DefaultPlatformToolset.empty()) {
175       e << this->GetName()
176         << " supports Windows Store '8.0' and '8.1', but "
177            "not '"
178         << this->SystemVersion << "'.  Check CMAKE_SYSTEM_VERSION.";
179     } else {
180       e << "A Windows Store component with CMake requires both the Windows "
181         << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
182         << "' SDK. Please make sure that you have both installed";
183     }
184     mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
185     return false;
186   }
187   return true;
188 }
189
190 bool cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset(
191   std::string& toolset) const
192 {
193   if (this->SystemVersion == "8.1") {
194     if (this->IsWindowsPhoneToolsetInstalled() &&
195         this->IsWindowsDesktopToolsetInstalled()) {
196       toolset = "v120_wp81";
197       return true;
198     } else {
199       return false;
200     }
201   }
202   return this->cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
203     toolset);
204 }
205
206 bool cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(
207   std::string& toolset) const
208 {
209   if (this->SystemVersion == "8.1") {
210     if (this->IsWindowsStoreToolsetInstalled() &&
211         this->IsWindowsDesktopToolsetInstalled()) {
212       toolset = "v120";
213       return true;
214     } else {
215       return false;
216     }
217   }
218   return this->cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
219     toolset);
220 }
221
222 bool cmGlobalVisualStudio12Generator::IsWindowsDesktopToolsetInstalled() const
223 {
224   const char desktop81Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
225                               "VisualStudio\\12.0\\VC\\LibraryDesktop";
226
227   std::vector<std::string> subkeys;
228   return cmSystemTools::GetRegistrySubKeys(desktop81Key, subkeys,
229                                            cmSystemTools::KeyWOW64_32);
230 }
231
232 bool cmGlobalVisualStudio12Generator::IsWindowsPhoneToolsetInstalled() const
233 {
234   const char wp81Key[] =
235     "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
236     "Microsoft SDKs\\WindowsPhone\\v8.1\\Install Path;Install Path";
237
238   std::string path;
239   cmSystemTools::ReadRegistryValue(wp81Key, path, cmSystemTools::KeyWOW64_32);
240   return !path.empty();
241 }
242
243 bool cmGlobalVisualStudio12Generator::IsWindowsStoreToolsetInstalled() const
244 {
245   const char win81Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
246                           "VisualStudio\\12.0\\VC\\Libraries\\Core\\Arm";
247
248   std::vector<std::string> subkeys;
249   return cmSystemTools::GetRegistrySubKeys(win81Key, subkeys,
250                                            cmSystemTools::KeyWOW64_32);
251 }