cmGlobalVisualStudio11Generator.cxx 11 KB

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