cmLocalVisualStudio10Generator.cxx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 "cmLocalVisualStudio10Generator.h"
  4. #include "cmGeneratorTarget.h"
  5. #include "cmGlobalVisualStudio10Generator.h"
  6. #include "cmMakefile.h"
  7. #include "cmVisualStudio10TargetGenerator.h"
  8. #include "cmXMLParser.h"
  9. #include "cmake.h"
  10. #include "cm_expat.h"
  11. class cmVS10XMLParser : public cmXMLParser
  12. {
  13. public:
  14. virtual void EndElement(const std::string& /* name */) {}
  15. virtual void CharacterDataHandler(const char* data, int length)
  16. {
  17. if (this->DoGUID) {
  18. if (data[0] == '{') {
  19. // remove surrounding curly brackets
  20. this->GUID.assign(data + 1, length - 2);
  21. } else {
  22. this->GUID.assign(data, length);
  23. }
  24. this->DoGUID = false;
  25. }
  26. }
  27. virtual void StartElement(const std::string& name, const char**)
  28. {
  29. // once the GUID is found do nothing
  30. if (!this->GUID.empty()) {
  31. return;
  32. }
  33. if ("ProjectGUID" == name || "ProjectGuid" == name) {
  34. this->DoGUID = true;
  35. }
  36. }
  37. int InitializeParser()
  38. {
  39. this->DoGUID = false;
  40. int ret = cmXMLParser::InitializeParser();
  41. if (ret == 0) {
  42. return ret;
  43. }
  44. // visual studio projects have a strange encoding, but it is
  45. // really utf-8
  46. XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
  47. return 1;
  48. }
  49. std::string GUID;
  50. bool DoGUID;
  51. };
  52. cmLocalVisualStudio10Generator::cmLocalVisualStudio10Generator(
  53. cmGlobalGenerator* gg, cmMakefile* mf)
  54. : cmLocalVisualStudio7Generator(gg, mf)
  55. {
  56. }
  57. cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator()
  58. {
  59. }
  60. void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
  61. cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
  62. {
  63. if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
  64. return;
  65. }
  66. // Find this target in the list of remaining targets.
  67. auto it = std::find(remaining.begin(), remaining.end(), target);
  68. if (it == remaining.end()) {
  69. // This target was already handled.
  70. return;
  71. }
  72. // Remove this target from the list of remaining targets because
  73. // we are handling it now.
  74. *it = nullptr;
  75. auto& deps = this->GlobalGenerator->GetTargetDirectDepends(target);
  76. for (auto& d : deps) {
  77. // FIXME: Revise CreateSingleVCProj so we do not have to drop `const` here.
  78. auto dependee = const_cast<cmGeneratorTarget*>(&*d);
  79. GenerateTargetsDepthFirst(dependee, remaining);
  80. // Take the union of visited source files of custom commands
  81. auto visited = GetSourcesVisited(dependee);
  82. GetSourcesVisited(target).insert(visited.begin(), visited.end());
  83. }
  84. if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
  85. ->TargetIsFortranOnly(target)) {
  86. this->CreateSingleVCProj(target->GetName(), target);
  87. } else {
  88. cmVisualStudio10TargetGenerator tg(
  89. target,
  90. static_cast<cmGlobalVisualStudio10Generator*>(
  91. this->GetGlobalGenerator()));
  92. tg.Generate();
  93. }
  94. }
  95. void cmLocalVisualStudio10Generator::Generate()
  96. {
  97. std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
  98. for (auto& t : remaining) {
  99. if (t) {
  100. GenerateTargetsDepthFirst(t, remaining);
  101. }
  102. }
  103. this->WriteStampFiles();
  104. }
  105. void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
  106. const std::string& name, const char* path)
  107. {
  108. cmVS10XMLParser parser;
  109. parser.ParseFile(path);
  110. // if we can not find a GUID then we will generate one later
  111. if (parser.GUID.empty()) {
  112. return;
  113. }
  114. std::string guidStoreName = name;
  115. guidStoreName += "_GUID_CMAKE";
  116. // save the GUID in the cache
  117. this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
  118. guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID",
  119. cmStateEnums::INTERNAL);
  120. }
  121. const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
  122. {
  123. return ":VCEnd";
  124. }