cmGlobalVisualStudio11Generator.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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 "cmLocalVisualStudio10Generator.h"
  12. #include "cmMakefile.h"
  13. #include "cmAlgorithms.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. {
  21. return 0;
  22. }
  23. const char* p = name.c_str() + sizeof(vs11generatorName) - 6;
  24. if(cmHasLiteralPrefix(p, " 2012"))
  25. {
  26. p += 5;
  27. }
  28. genName = std::string(vs11generatorName) + p;
  29. return p;
  30. }
  31. class cmGlobalVisualStudio11Generator::Factory
  32. : public cmGlobalGeneratorFactory
  33. {
  34. public:
  35. virtual cmGlobalGenerator* CreateGlobalGenerator(
  36. const std::string& name) const
  37. {
  38. std::string genName;
  39. const char* p = cmVS11GenName(name, genName);
  40. if(!p)
  41. { return 0; }
  42. if(!*p)
  43. {
  44. return new cmGlobalVisualStudio11Generator(
  45. genName, "");
  46. }
  47. if(*p++ != ' ')
  48. { return 0; }
  49. if(strcmp(p, "Win64") == 0)
  50. {
  51. return new cmGlobalVisualStudio11Generator(
  52. genName, "x64");
  53. }
  54. if(strcmp(p, "ARM") == 0)
  55. {
  56. return new cmGlobalVisualStudio11Generator(
  57. genName, "ARM");
  58. }
  59. std::set<std::string> installedSDKs =
  60. cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
  61. if(installedSDKs.find(p) == installedSDKs.end())
  62. {
  63. return 0;
  64. }
  65. cmGlobalVisualStudio11Generator* ret =
  66. new cmGlobalVisualStudio11Generator(name, p);
  67. ret->WindowsCEVersion = "8.00";
  68. return ret;
  69. }
  70. virtual void GetDocumentation(cmDocumentationEntry& entry) const
  71. {
  72. entry.Name = std::string(vs11generatorName) + " [arch]";
  73. entry.Brief =
  74. "Generates Visual Studio 2012 project files. "
  75. "Optional [arch] can be \"Win64\" or \"ARM\"."
  76. ;
  77. }
  78. virtual void GetGenerators(std::vector<std::string>& names) const
  79. {
  80. names.push_back(vs11generatorName);
  81. names.push_back(vs11generatorName + std::string(" ARM"));
  82. names.push_back(vs11generatorName + std::string(" Win64"));
  83. std::set<std::string> installedSDKs =
  84. cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
  85. for(std::set<std::string>::const_iterator i =
  86. installedSDKs.begin(); i != installedSDKs.end(); ++i)
  87. {
  88. names.push_back(std::string(vs11generatorName) + " " + *i);
  89. }
  90. }
  91. };
  92. //----------------------------------------------------------------------------
  93. cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
  94. {
  95. return new Factory;
  96. }
  97. //----------------------------------------------------------------------------
  98. cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
  99. const std::string& name, const std::string& platformName)
  100. : cmGlobalVisualStudio10Generator(name, platformName)
  101. {
  102. std::string vc11Express;
  103. this->ExpressEdition = cmSystemTools::ReadRegistryValue(
  104. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;"
  105. "ProductDir", vc11Express, cmSystemTools::KeyWOW64_32);
  106. this->DefaultPlatformToolset = "v110";
  107. }
  108. //----------------------------------------------------------------------------
  109. bool
  110. cmGlobalVisualStudio11Generator::MatchesGeneratorName(
  111. const std::string& name) const
  112. {
  113. std::string genName;
  114. if(cmVS11GenName(name, genName))
  115. {
  116. return genName == this->GetName();
  117. }
  118. return false;
  119. }
  120. //----------------------------------------------------------------------------
  121. bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
  122. {
  123. if(!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset))
  124. {
  125. std::ostringstream e;
  126. if(this->DefaultPlatformToolset.empty())
  127. {
  128. e << this->GetName() << " supports Windows Phone '8.0', but not '"
  129. << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
  130. }
  131. else
  132. {
  133. e << "A Windows Phone component with CMake requires both the Windows "
  134. << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
  135. << "' SDK. Please make sure that you have both installed";
  136. }
  137. mf->IssueMessage(cmake::FATAL_ERROR, e.str());
  138. return false;
  139. }
  140. return true;
  141. }
  142. //----------------------------------------------------------------------------
  143. bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
  144. {
  145. if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset))
  146. {
  147. std::ostringstream e;
  148. if(this->DefaultPlatformToolset.empty())
  149. {
  150. e << this->GetName() << " supports Windows Store '8.0', but not '"
  151. << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
  152. }
  153. else
  154. {
  155. e << "A Windows Store component with CMake requires both the Windows "
  156. << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
  157. << "' SDK. Please make sure that you have both installed";
  158. }
  159. mf->IssueMessage(cmake::FATAL_ERROR, e.str());
  160. return false;
  161. }
  162. return true;
  163. }
  164. //----------------------------------------------------------------------------
  165. bool
  166. cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
  167. std::string& toolset) const
  168. {
  169. if(this->SystemVersion == "8.0")
  170. {
  171. if (this->IsWindowsPhoneToolsetInstalled() &&
  172. this->IsWindowsDesktopToolsetInstalled())
  173. {
  174. toolset = "v110_wp80";
  175. return true;
  176. }
  177. else
  178. {
  179. return false;
  180. }
  181. }
  182. return
  183. this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(toolset);
  184. }
  185. //----------------------------------------------------------------------------
  186. bool
  187. cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
  188. std::string& toolset) const
  189. {
  190. if(this->SystemVersion == "8.0")
  191. {
  192. if(this->IsWindowsStoreToolsetInstalled() &&
  193. this->IsWindowsDesktopToolsetInstalled())
  194. {
  195. toolset = "v110";
  196. return true;
  197. }
  198. else
  199. {
  200. return false;
  201. }
  202. }
  203. return
  204. this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(toolset);
  205. }
  206. //----------------------------------------------------------------------------
  207. void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
  208. {
  209. fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
  210. if (this->ExpressEdition)
  211. {
  212. fout << "# Visual Studio Express 2012 for Windows Desktop\n";
  213. }
  214. else
  215. {
  216. fout << "# Visual Studio 2012\n";
  217. }
  218. }
  219. //----------------------------------------------------------------------------
  220. cmLocalGenerator *
  221. cmGlobalVisualStudio11Generator::CreateLocalGenerator(cmLocalGenerator* parent)
  222. {
  223. return new cmLocalVisualStudio10Generator(
  224. cmLocalVisualStudioGenerator::VS11, this, parent);
  225. }
  226. //----------------------------------------------------------------------------
  227. bool cmGlobalVisualStudio11Generator::UseFolderProperty()
  228. {
  229. // Intentionally skip over the parent class implementation and call the
  230. // grand-parent class's implementation. Folders are not supported by the
  231. // Express editions in VS10 and earlier, but they are in VS11 Express.
  232. return cmGlobalVisualStudio8Generator::UseFolderProperty();
  233. }
  234. //----------------------------------------------------------------------------
  235. std::set<std::string>
  236. cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs()
  237. {
  238. const char sdksKey[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  239. "Windows CE Tools\\SDKs";
  240. std::vector<std::string> subkeys;
  241. cmSystemTools::GetRegistrySubKeys(sdksKey, subkeys,
  242. cmSystemTools::KeyWOW64_32);
  243. std::set<std::string> ret;
  244. for(std::vector<std::string>::const_iterator i =
  245. subkeys.begin(); i != subkeys.end(); ++i)
  246. {
  247. std::string key = sdksKey;
  248. key += '\\';
  249. key += *i;
  250. key += ';';
  251. std::string path;
  252. if(cmSystemTools::ReadRegistryValue(key.c_str(),
  253. path,
  254. cmSystemTools::KeyWOW64_32) &&
  255. !path.empty())
  256. {
  257. ret.insert(*i);
  258. }
  259. }
  260. return ret;
  261. }
  262. //----------------------------------------------------------------------------
  263. bool
  264. cmGlobalVisualStudio11Generator::NeedsDeploy(cmTarget::TargetType type) const
  265. {
  266. if((type == cmTarget::EXECUTABLE ||
  267. type == cmTarget::SHARED_LIBRARY) &&
  268. (this->SystemIsWindowsPhone ||
  269. this->SystemIsWindowsStore))
  270. {
  271. return true;
  272. }
  273. return cmGlobalVisualStudio10Generator::NeedsDeploy(type);
  274. }
  275. //----------------------------------------------------------------------------
  276. bool
  277. cmGlobalVisualStudio11Generator::IsWindowsDesktopToolsetInstalled() const
  278. {
  279. const char desktop80Key[] =
  280. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  281. "VisualStudio\\11.0\\VC\\Libraries\\Extended";
  282. const char VS2012DesktopExpressKey[] =
  283. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  284. "WDExpress\\11.0;InstallDir";
  285. std::vector<std::string> subkeys;
  286. std::string path;
  287. return cmSystemTools::ReadRegistryValue(VS2012DesktopExpressKey,
  288. path,
  289. cmSystemTools::KeyWOW64_32) ||
  290. cmSystemTools::GetRegistrySubKeys(desktop80Key,
  291. subkeys,
  292. cmSystemTools::KeyWOW64_32);
  293. }
  294. //----------------------------------------------------------------------------
  295. bool
  296. cmGlobalVisualStudio11Generator::IsWindowsPhoneToolsetInstalled() const
  297. {
  298. const char wp80Key[] =
  299. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  300. "Microsoft SDKs\\WindowsPhone\\v8.0\\"
  301. "Install Path;Install Path";
  302. std::string path;
  303. cmSystemTools::ReadRegistryValue(wp80Key,
  304. path,
  305. cmSystemTools::KeyWOW64_32);
  306. return !path.empty();
  307. }
  308. //----------------------------------------------------------------------------
  309. bool
  310. cmGlobalVisualStudio11Generator::IsWindowsStoreToolsetInstalled() const
  311. {
  312. const char win80Key[] =
  313. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
  314. "VisualStudio\\11.0\\VC\\Libraries\\Core\\Arm";
  315. std::vector<std::string> subkeys;
  316. return cmSystemTools::GetRegistrySubKeys(win80Key,
  317. subkeys,
  318. cmSystemTools::KeyWOW64_32);
  319. }