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 "cmGlobalVisualStudio11Generator.h"
10 #include "cmDocumentationEntry.h"
11 #include "cmGlobalGenerator.h"
12 #include "cmGlobalGeneratorFactory.h"
13 #include "cmGlobalVisualStudioGenerator.h"
14 #include "cmMakefile.h"
15 #include "cmMessageType.h"
16 #include "cmStringAlgorithms.h"
17 #include "cmSystemTools.h"
19 static const char vs11generatorName[] = "Visual Studio 11 2012";
21 // Map generator name without year to name with year.
22 static const char* cmVS11GenName(const std::string& name, std::string& genName)
24 if (strncmp(name.c_str(), vs11generatorName,
25 sizeof(vs11generatorName) - 6) != 0) {
28 const char* p = name.c_str() + sizeof(vs11generatorName) - 6;
29 if (cmHasLiteralPrefix(p, " 2012")) {
32 genName = std::string(vs11generatorName) + p;
36 class cmGlobalVisualStudio11Generator::Factory
37 : public cmGlobalGeneratorFactory
40 std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
41 const std::string& name, bool allowArch, cmake* cm) const override
44 const char* p = cmVS11GenName(name, genName);
46 return std::unique_ptr<cmGlobalGenerator>();
49 return std::unique_ptr<cmGlobalGenerator>(
50 new cmGlobalVisualStudio11Generator(cm, genName, ""));
52 if (!allowArch || *p++ != ' ') {
53 return std::unique_ptr<cmGlobalGenerator>();
55 if (strcmp(p, "Win64") == 0) {
56 return std::unique_ptr<cmGlobalGenerator>(
57 new cmGlobalVisualStudio11Generator(cm, genName, "x64"));
59 if (strcmp(p, "ARM") == 0) {
60 return std::unique_ptr<cmGlobalGenerator>(
61 new cmGlobalVisualStudio11Generator(cm, genName, "ARM"));
64 std::set<std::string> installedSDKs =
65 cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
67 if (installedSDKs.find(p) == installedSDKs.end()) {
68 return std::unique_ptr<cmGlobalGenerator>();
71 auto ret = std::unique_ptr<cmGlobalVisualStudio11Generator>(
72 new cmGlobalVisualStudio11Generator(cm, name, p));
73 ret->WindowsCEVersion = "8.00";
74 return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
77 void GetDocumentation(cmDocumentationEntry& entry) const override
79 entry.Name = std::string(vs11generatorName) + " [arch]";
80 entry.Brief = "Generates Visual Studio 2012 project files. "
81 "Optional [arch] can be \"Win64\" or \"ARM\".";
84 std::vector<std::string> GetGeneratorNames() const override
86 std::vector<std::string> names;
87 names.push_back(vs11generatorName);
91 std::vector<std::string> GetGeneratorNamesWithPlatform() const override
93 std::vector<std::string> names;
94 names.push_back(vs11generatorName + std::string(" ARM"));
95 names.push_back(vs11generatorName + std::string(" Win64"));
97 std::set<std::string> installedSDKs =
98 cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
99 for (std::string const& i : installedSDKs) {
100 names.push_back(std::string(vs11generatorName) + " " + i);
106 bool SupportsToolset() const override { return true; }
107 bool SupportsPlatform() const override { return true; }
109 std::vector<std::string> GetKnownPlatforms() const override
111 std::vector<std::string> platforms;
112 platforms.emplace_back("x64");
113 platforms.emplace_back("Win32");
114 platforms.emplace_back("ARM");
116 std::set<std::string> installedSDKs =
117 cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
118 for (std::string const& i : installedSDKs) {
119 platforms.emplace_back(i);
125 std::string GetDefaultPlatformName() const override { return "Win32"; }
128 std::unique_ptr<cmGlobalGeneratorFactory>
129 cmGlobalVisualStudio11Generator::NewFactory()
131 return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
134 cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
135 cmake* cm, const std::string& name,
136 std::string const& platformInGeneratorName)
137 : cmGlobalVisualStudio10Generator(cm, name, platformInGeneratorName)
139 std::string vc11Express;
140 this->ExpressEdition = cmSystemTools::ReadRegistryValue(
141 "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;"
143 vc11Express, cmSystemTools::KeyWOW64_32);
144 this->DefaultPlatformToolset = "v110";
145 this->DefaultCLFlagTableName = "v11";
146 this->DefaultCSharpFlagTableName = "v11";
147 this->DefaultLibFlagTableName = "v11";
148 this->DefaultLinkFlagTableName = "v11";
149 this->DefaultMasmFlagTableName = "v11";
150 this->DefaultRCFlagTableName = "v11";
151 this->Version = VSVersion::VS11;
154 bool cmGlobalVisualStudio11Generator::MatchesGeneratorName(
155 const std::string& name) const
158 if (cmVS11GenName(name, genName)) {
159 return genName == this->GetName();
164 bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
166 if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
167 std::ostringstream e;
168 if (this->DefaultPlatformToolset.empty()) {
169 e << this->GetName() << " supports Windows Phone '8.0', but not '"
170 << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
172 e << "A Windows Phone component with CMake requires both the Windows "
173 << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
174 << "' SDK. Please make sure that you have both installed";
176 mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
182 bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
184 if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
185 std::ostringstream e;
186 if (this->DefaultPlatformToolset.empty()) {
187 e << this->GetName() << " supports Windows Store '8.0', but not '"
188 << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
190 e << "A Windows Store component with CMake requires both the Windows "
191 << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
192 << "' SDK. Please make sure that you have both installed";
194 mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
200 bool cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
201 std::string& toolset) const
203 if (this->SystemVersion == "8.0") {
204 if (this->IsWindowsPhoneToolsetInstalled() &&
205 this->IsWindowsDesktopToolsetInstalled()) {
206 toolset = "v110_wp80";
212 return this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
216 bool cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
217 std::string& toolset) const
219 if (this->SystemVersion == "8.0") {
220 if (this->IsWindowsStoreToolsetInstalled() &&
221 this->IsWindowsDesktopToolsetInstalled()) {
228 return this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(
232 bool cmGlobalVisualStudio11Generator::UseFolderProperty() const
234 // Intentionally skip up to the top-level class implementation.
235 // Folders are not supported by the Express editions in VS10 and earlier,
236 // but they are in VS11 Express and above.
237 return cmGlobalGenerator::UseFolderProperty();
240 std::set<std::string>
241 cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs()
243 const char sdksKey[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
244 "Windows CE Tools\\SDKs";
246 std::vector<std::string> subkeys;
247 cmSystemTools::GetRegistrySubKeys(sdksKey, subkeys,
248 cmSystemTools::KeyWOW64_32);
250 std::set<std::string> ret;
251 for (std::string const& i : subkeys) {
252 std::string key = sdksKey;
258 if (cmSystemTools::ReadRegistryValue(key, path,
259 cmSystemTools::KeyWOW64_32) &&
268 bool cmGlobalVisualStudio11Generator::TargetSystemSupportsDeployment() const
270 return this->SystemIsWindowsPhone || this->SystemIsWindowsStore ||
271 cmGlobalVisualStudio10Generator::TargetSystemSupportsDeployment();
274 bool cmGlobalVisualStudio11Generator::IsWindowsDesktopToolsetInstalled() const
276 const char desktop80Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
277 "VisualStudio\\11.0\\VC\\Libraries\\Extended";
278 const char VS2012DesktopExpressKey[] =
279 "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
280 "WDExpress\\11.0;InstallDir";
282 std::vector<std::string> subkeys;
284 return cmSystemTools::ReadRegistryValue(VS2012DesktopExpressKey, path,
285 cmSystemTools::KeyWOW64_32) ||
286 cmSystemTools::GetRegistrySubKeys(desktop80Key, subkeys,
287 cmSystemTools::KeyWOW64_32);
290 bool cmGlobalVisualStudio11Generator::IsWindowsPhoneToolsetInstalled() const
292 const char wp80Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
293 "Microsoft SDKs\\WindowsPhone\\v8.0\\"
294 "Install Path;Install Path";
297 cmSystemTools::ReadRegistryValue(wp80Key, path, cmSystemTools::KeyWOW64_32);
298 return !path.empty();
301 bool cmGlobalVisualStudio11Generator::IsWindowsStoreToolsetInstalled() const
303 const char win80Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
304 "VisualStudio\\11.0\\VC\\Libraries\\Core\\Arm";
306 std::vector<std::string> subkeys;
307 return cmSystemTools::GetRegistrySubKeys(win80Key, subkeys,
308 cmSystemTools::KeyWOW64_32);