1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* 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 "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmVisualStudio10TargetGenerator.h"
#include "cmXMLParser.h"
#include "cm_expat.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 = this->GetGeneratorTargets();
for (auto& t : remaining) {
if (t) {
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 = name;
guidStoreName += "_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";
}
|