/* 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 #include "cm_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(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& 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(&*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(this->GlobalGenerator) ->TargetIsFortranOnly(target)) { this->CreateSingleVCProj(target->GetName(), target); } else { cmVisualStudio10TargetGenerator tg( target, static_cast( this->GetGlobalGenerator())); tg.Generate(); } } void cmLocalVisualStudio10Generator::Generate() { std::vector 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.c_str(), parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL); } const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const { return ":VCEnd"; }