cmGlobalVisualStudio11Generator.cxx 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmGlobalVisualStudio11Generator.h"
  11. #include "cmAlgorithms.h"
  12. #include "cmLocalVisualStudio10Generator.h"
  13. #include "cmMakefile.h"
  14. static const char vs11generatorName[] = "Visual Studio 11 2012";
  15. // Map generator name without year to name with year.
  16. static const char* cmVS11GenName(const std::string& name, std::string& genName)
  17. {
  18. if (strncmp(name.c_str(), vs11generatorName,
  19. sizeof(vs11generatorName) - 6) != 0) {
  20. return 0;
  21. }
  22. const char* p = name.c_str() + sizeof(vs11generatorName) - 6;
  23. if (cmHasLiteralPrefix(p, " 2012")) {
  24. p += 5;
  25. }
  26. genName = std::string(vs11generatorName) + p;
  27. return p;
  28. }
  29. class cmGlobalVisualStudio11Generator::Factory
  30. : public cmGlobalGeneratorFactory
  31. {
  32. public:
  33. cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
  34. cmake* cm) const CM_OVERRIDE
  35. {
  36. std::string genName;
  37. const char* p = cmVS11GenName(name, genName);
  38. if (!p) {
  39. return 0;
  40. }
  41. if (!*p) {
  42. return new cmGlobalVisualStudio11Generator(cm, genName, "");
  43. }
  44. if (*p++ != ' ') {
  45. return 0;
  46. }
  47. if (strcmp(p, "Win64") == 0) {
  48. return new cmGlobalVisualStudio11Generator(cm, genName, "x64");
  49. }
  50. if (strcmp(p, "ARM") == 0) {
  51. return new cmGlobalVisualStudio11Generator(cm, genName, "ARM");
  52. }
  53. std::set<std::string> installedSDKs =
  54. cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
  55. if (installedSDKs.find(p) == installedSDKs.end()) {
  56. return 0;
  57. }
  58. cmGlobalVisualStudio11Generator* ret =
  59. new cmGlobalVisualStudio11Generator(cm, name, p);
  60. ret->WindowsCEVersion = "8.00";
  61. return ret;
  62. }
  63. void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
  64. {
  65. entry.Name = std::string(vs11generatorName) + " [arch]";
  66. entry.Brief = "Generates Visual Studio 2012 project files. "
  67. "Optional [arch] can be \"Win64\" or \"ARM\".";
  68. }
  69. void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
  70. {
  71. names.push_back(vs11generatorName);
  72. names.push_back(vs11generatorName + std::string(" ARM"));
  73. names.push_back(vs11generatorName + std::string(" Win64"));
  74. std::set<std::string> installedSDKs =
  75. cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
  76. for (std::set<std::string>::const_iterator i = installedSDKs.begin();
  77. i != installedSDKs.end(); ++i) {
  78. names.push_back(std::string(vs11generatorName) + " " + *i);
  79. }
  80. }
  81. bool SupportsToolset() const CM_OVERRIDE { return true; }
  82. bool SupportsPlatform() const CM_OVERRIDE { return true; }
  83. };
  84. cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
  85. {
  86. return new Factory;
  87. }
  88. cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
  89. cmake* cm, const std::string& name, const std::string& platformName)
  90. : cmGlobalVisualStudio10Generator(cm, name, platformName)
  91. {
  92. std::string vc11Express;
  93. this->ExpressEdition = cmSystemTools::ReadRegistryValue(
  94. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;"
  95. "ProductDir",
  96. vc11Express, cmSystemTools::KeyWOW64_32);
  97. this->DefaultPlatformToolset = "v110";
  98. this->Version = VS11;
  99. }
  100. bool cmGlobalVisualStudio11Generator::MatchesGeneratorName(
  101. const std::string& name) const
  102. {
  103. std::string genName;
  104. if (cmVS11GenName(name, genName)) {
  105. return genName == this->GetName();
  106. }
  107. return false;
  108. }
  109. bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
  110. {
  111. if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
  112. std::ostringstream e;
  113. if (this->DefaultPlatformToolset.empty()) {
  114. e << this->GetName() << " supports Windows Phone '8.0', but not '"
  115. << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
  116. } else {
  117. e << "A Windows Phone component with CMake requires both the Windows "
  118. << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
  119. << "' SDK. Please make sure that you have both installed";
  120. }
  121. mf->IssueMessage(cmake::FATAL_ERROR, e.str());
  122. return false;
  123. }
  124. return true;
  125. }
  126. bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
  127. {
  128. if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
  129. std::ostringstream e;
  130. if (this->DefaultPlatformToolset.empty()) {
  131. e << this->GetName() << " supports Windows Store '8.0', but not '"
  132. << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
  133. } else {
  134. e << "A Windows Store component with CMake requires both the Windows "
  135. << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
  136. << "' SDK. Please make sure that you have both installed";
  137. }
  138. mf->IssueMessage(cmake::FATAL_ERROR, e.str());
  139. return false;
  140. }
  141. return true;
  142. }
  143. bool cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
  144. std::string& toolset) const
  145. {
  146. if (this->SystemVersion == "8.0") {
  147. if (this->IsWindowsPhoneToolsetInstalled() &&
  148. this->IsWindowsDesktopToolsetInstalled()) {
  149. toolset = "v110_wp80";
  150. return true;
  151. } else {
  152. return false;
  153. }
  154. }
  155. return this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
  156. toolset);
  157. }
  158. bool cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
  159. std::string& toolset) const
  160. {
  161. if (this->SystemVersion == "8.0") {
  162. if (this->IsWindowsStoreToolsetInstalled() &&
  163. this->IsWindowsDesktopToolsetInstalled()) {
  164. toolset = "v110";
  165. return true;
  166. } else {
  167. return false;
  168. }
  169. }
  170. return this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(
  171. toolset);
  172. }
  173. void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
  174. {
  175. fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
  176. if (this->ExpressEdition) {
  177. fout << "# Visual Studio Express 2012 for Windows Desktop\n";
  178. } else {
  179. fout << "# Visual Studio 2012\n";
  180. }
  181. }
  182. bool cmGlobalVisualStudio11Generator::UseFolderProperty()
  183. {
  184. // Intentionally skip up to the top-level class implementation.
  185. // Folders are not supported by the Express editions in VS10 and earlier,
  186. // but they are in VS11 Express and above.
  187. return cmGlobalGenerator::UseFolderProperty();
  188. }
  189. std::set<std::string>
  190. cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs()
  191. {
  192. const char sdksKey[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  193. "Windows CE Tools\\SDKs";
  194. std::vector<std::string> subkeys;
  195. cmSystemTools::GetRegistrySubKeys(sdksKey, subkeys,
  196. cmSystemTools::KeyWOW64_32);
  197. std::set<std::string> ret;
  198. for (std::vector<std::string>::const_iterator i = subkeys.begin();
  199. i != subkeys.end(); ++i) {
  200. std::string key = sdksKey;
  201. key += '\\';
  202. key += *i;
  203. key += ';';
  204. std::string path;
  205. if (cmSystemTools::ReadRegistryValue(key.c_str(), path,
  206. cmSystemTools::KeyWOW64_32) &&
  207. !path.empty()) {
  208. ret.insert(*i);
  209. }
  210. }
  211. return ret;
  212. }
  213. bool cmGlobalVisualStudio11Generator::NeedsDeploy(
  214. cmState::TargetType type) const
  215. {
  216. if ((type == cmState::EXECUTABLE || type == cmState::SHARED_LIBRARY) &&
  217. (this->SystemIsWindowsPhone || this->SystemIsWindowsStore)) {
  218. return true;
  219. }
  220. return cmGlobalVisualStudio10Generator::NeedsDeploy(type);
  221. }
  222. bool cmGlobalVisualStudio11Generator::IsWindowsDesktopToolsetInstalled() const
  223. {
  224. const char desktop80Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  225. "VisualStudio\\11.0\\VC\\Libraries\\Extended";
  226. const char VS2012DesktopExpressKey[] =
  227. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  228. "WDExpress\\11.0;InstallDir";
  229. std::vector<std::string> subkeys;
  230. std::string path;
  231. return cmSystemTools::ReadRegistryValue(VS2012DesktopExpressKey, path,
  232. cmSystemTools::KeyWOW64_32) ||
  233. cmSystemTools::GetRegistrySubKeys(desktop80Key, subkeys,
  234. cmSystemTools::KeyWOW64_32);
  235. }
  236. bool cmGlobalVisualStudio11Generator::IsWindowsPhoneToolsetInstalled() const
  237. {
  238. const char wp80Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  239. "Microsoft SDKs\\WindowsPhone\\v8.0\\"
  240. "Install Path;Install Path";
  241. std::string path;
  242. cmSystemTools::ReadRegistryValue(wp80Key, path, cmSystemTools::KeyWOW64_32);
  243. return !path.empty();
  244. }
  245. bool cmGlobalVisualStudio11Generator::IsWindowsStoreToolsetInstalled() const
  246. {
  247. const char win80Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  248. "VisualStudio\\11.0\\VC\\Libraries\\Core\\Arm";
  249. std::vector<std::string> subkeys;
  250. return cmSystemTools::GetRegistrySubKeys(win80Key, subkeys,
  251. cmSystemTools::KeyWOW64_32);
  252. }