Xcode: Save object id values in CMakeCache.txt (#11690)

For project and target objects, save their ids in CMakeCache.txt.

Hopefully, that will be enough to allow user settings to be saved
across multiple CMake generate operations. Other object types may
also need their ids saved: if so, more code than this commit
will be necessary...
This commit is contained in:
David Cole 2011-08-23 18:22:33 -04:00
parent fe46e7e486
commit 1834f232a7
4 changed files with 89 additions and 21 deletions

View File

@ -489,12 +489,34 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
delete this->XCodeObjects[i];
}
this->XCodeObjects.clear();
this->XCodeObjectIDs.clear();
this->GroupMap.clear();
this->GroupNameMap.clear();
this->TargetGroup.clear();
this->FileRefs.clear();
}
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::addObject(cmXCodeObject *obj)
{
if(obj->GetType() == cmXCodeObject::OBJECT)
{
cmStdString id = obj->GetId();
// If this is a duplicate id, it's an error:
//
if(this->XCodeObjectIDs.count(id))
{
cmSystemTools::Error(
"Xcode generator: duplicate object ids not allowed");
}
this->XCodeObjectIDs.insert(id);
}
this->XCodeObjects.push_back(obj);
}
//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
@ -508,7 +530,7 @@ cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
{
obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
}
this->XCodeObjects.push_back(obj);
this->addObject(obj);
return obj;
}
@ -517,7 +539,7 @@ cmXCodeObject*
cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
{
cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
this->XCodeObjects.push_back(obj);
this->addObject(obj);
return obj;
}
@ -2040,6 +2062,9 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
}
}
target->SetId(this->GetOrCreateId(
cmtarget.GetName(), target->GetId()).c_str());
return target;
}
@ -2188,6 +2213,8 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
target->AddAttribute("productType", this->CreateString(productType));
}
target->SetTarget(&cmtarget);
target->SetId(this->GetOrCreateId(
cmtarget.GetName(), target->GetId()).c_str());
return target;
}
@ -2210,6 +2237,26 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
return 0;
}
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name,
const char* id)
{
std::string guidStoreName = name;
guidStoreName += "_GUID_CMAKE";
const char* storedGUID =
this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
if(storedGUID)
{
return storedGUID;
}
this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
id, "Stored Xcode object GUID", cmCacheManager::INTERNAL);
return id;
}
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
cmXCodeObject* dependTarget)
@ -2739,6 +2786,12 @@ void cmGlobalXCodeGenerator
this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
this->RootObject->SetComment("Project object");
std::string project_id = "PROJECT_";
project_id += root->GetMakefile()->GetProjectName();
this->RootObject->SetId(this->GetOrCreateId(
project_id.c_str(), this->RootObject->GetId()).c_str());
group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
this->RootObject->AddAttribute("mainGroup",
this->CreateObjectReference(mainGroup));
@ -3137,6 +3190,11 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
}
this->WriteXCodePBXProj(fout, root, generators);
this->ClearXCodeObjects();
// Since this call may have created new cache entries, save the cache:
//
root->GetMakefile()->GetCacheManager()->SaveCache(
root->GetMakefile()->GetHomeOutputDirectory());
}
//----------------------------------------------------------------------------

View File

@ -123,6 +123,8 @@ private:
);
cmXCodeObject* FindXCodeTarget(cmTarget*);
std::string GetOrCreateId(const char* name, const char* id);
// create cmXCodeObject from these functions so that memory can be managed
// correctly. All objects created are stored in this->XCodeObjects.
cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype);
@ -197,9 +199,11 @@ protected:
unsigned int XcodeVersion;
std::string VersionString;
std::set<cmStdString> XCodeObjectIDs;
std::vector<cmXCodeObject*> XCodeObjects;
cmXCodeObject* RootObject;
private:
void addObject(cmXCodeObject *obj);
std::string PostBuildMakeTarget(std::string const& tName,
std::string const& configName);
cmXCodeObject* MainGroupChildren;

View File

@ -12,6 +12,8 @@
#include "cmXCodeObject.h"
#include "cmSystemTools.h"
#include <CoreFoundation/CoreFoundation.h> // CFUUIDCreate
//----------------------------------------------------------------------------
const char* cmXCodeObject::PBXTypeNames[] = {
"PBXGroup", "PBXBuildStyle", "PBXProject", "PBXHeadersBuildPhase",
@ -41,33 +43,33 @@ cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
this->Object =0;
this->IsA = ptype;
if(type == OBJECT)
{
cmOStringStream str;
str << (void*)this;
str << (void*)this;
str << (void*)this;
this->Id = str.str();
// Set the Id of an Xcode object to a unique string for each instance.
// However the Xcode user file references certain Ids: for those cases,
// override the generated Id using SetId().
//
char cUuid[40] = {0};
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid);
CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8);
this->Id = cUuid;
CFRelease(s);
CFRelease(uuid);
}
else
{
this->Id =
"Temporary cmake object, should not be refered to in xcode file";
}
cmSystemTools::ReplaceString(this->Id, "0x", "");
this->Id = cmSystemTools::UpperCase(this->Id);
if(this->Id.size() < 24)
{
int diff = 24 - this->Id.size();
for(int i =0; i < diff; ++i)
{
this->Id += "0";
}
"Temporary cmake object, should not be referred to in Xcode file";
}
cmSystemTools::ReplaceString(this->Id, "-", "");
if(this->Id.size() > 24)
{
this->Id = this->Id.substr(0, 24);
}
this->TypeValue = type;
if(this->TypeValue == OBJECT)
{

View File

@ -83,6 +83,10 @@ public:
{
return this->Id.c_str();
}
void SetId(const char* id)
{
this->Id = id;
}
cmTarget* GetTarget()
{
return this->Target;