| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmLocalVisualStudio10Generator.h" |
| |
| #include <cmext/algorithm> |
| |
| #include <cm3p/expat.h> |
| |
| #include "cmAlgorithms.h" |
| #include "cmGeneratorTarget.h" |
| #include "cmGlobalVisualStudio10Generator.h" |
| #include "cmMakefile.h" |
| #include "cmVisualStudio10TargetGenerator.h" |
| #include "cmXMLParser.h" |
| #include "cmake.h" |
| |
| class cmVS10XMLParser : public cmXMLParser |
| { |
| public: |
| virtual void EndElement(const std::string& /* name */) {} |
| virtual void CharacterDataHandler(const char* data, int length) |
| { |
| if (this->DoGUID) { |
| if (data[0] == '{') { |
| // remove surrounding curly brackets |
| this->GUID.assign(data + 1, length - 2); |
| } else { |
| this->GUID.assign(data, length); |
| } |
| this->DoGUID = false; |
| } |
| } |
| virtual void StartElement(const std::string& name, const char**) |
| { |
| // once the GUID is found do nothing |
| if (!this->GUID.empty()) { |
| return; |
| } |
| if ("ProjectGUID" == name || "ProjectGuid" == name) { |
| this->DoGUID = true; |
| } |
| } |
| int InitializeParser() |
| { |
| this->DoGUID = false; |
| int ret = cmXMLParser::InitializeParser(); |
| if (ret == 0) { |
| return ret; |
| } |
| // visual studio projects have a strange encoding, but it is |
| // really utf-8 |
| XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8"); |
| return 1; |
| } |
| std::string GUID; |
| bool DoGUID; |
| }; |
| |
| cmLocalVisualStudio10Generator::cmLocalVisualStudio10Generator( |
| cmGlobalGenerator* gg, cmMakefile* mf) |
| : cmLocalVisualStudio7Generator(gg, mf) |
| { |
| } |
| |
| cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator() |
| { |
| } |
| |
| void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst( |
| cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining) |
| { |
| if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { |
| return; |
| } |
| // Find this target in the list of remaining targets. |
| auto it = std::find(remaining.begin(), remaining.end(), target); |
| if (it == remaining.end()) { |
| // This target was already handled. |
| return; |
| } |
| // Remove this target from the list of remaining targets because |
| // we are handling it now. |
| *it = nullptr; |
| auto& deps = this->GlobalGenerator->GetTargetDirectDepends(target); |
| for (auto& d : deps) { |
| // FIXME: Revise CreateSingleVCProj so we do not have to drop `const` here. |
| auto dependee = const_cast<cmGeneratorTarget*>(&*d); |
| GenerateTargetsDepthFirst(dependee, remaining); |
| // Take the union of visited source files of custom commands |
| auto visited = GetSourcesVisited(dependee); |
| GetSourcesVisited(target).insert(visited.begin(), visited.end()); |
| } |
| if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator) |
| ->TargetIsFortranOnly(target)) { |
| this->CreateSingleVCProj(target->GetName(), target); |
| } else { |
| cmVisualStudio10TargetGenerator tg( |
| target, |
| static_cast<cmGlobalVisualStudio10Generator*>( |
| this->GetGlobalGenerator())); |
| tg.Generate(); |
| } |
| } |
| |
| void cmLocalVisualStudio10Generator::Generate() |
| { |
| std::vector<cmGeneratorTarget*> remaining; |
| cm::append(remaining, this->GetGeneratorTargets()); |
| for (auto& t : remaining) { |
| if (t) { |
| this->GenerateTargetsDepthFirst(t, remaining); |
| } |
| } |
| this->WriteStampFiles(); |
| } |
| |
| void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID( |
| const std::string& name, const char* path) |
| { |
| cmVS10XMLParser parser; |
| parser.ParseFile(path); |
| |
| // if we can not find a GUID then we will generate one later |
| if (parser.GUID.empty()) { |
| return; |
| } |
| |
| std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); |
| // save the GUID in the cache |
| this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry( |
| guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL); |
| } |
| |
| const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const |
| { |
| return ":VCEnd"; |
| } |