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]; delete this->XCodeObjects[i];
} }
this->XCodeObjects.clear(); this->XCodeObjects.clear();
this->XCodeObjectIDs.clear();
this->GroupMap.clear(); this->GroupMap.clear();
this->GroupNameMap.clear(); this->GroupNameMap.clear();
this->TargetGroup.clear(); this->TargetGroup.clear();
this->FileRefs.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* cmXCodeObject*
cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype) cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
@ -508,7 +530,7 @@ cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
{ {
obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT); obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
} }
this->XCodeObjects.push_back(obj); this->addObject(obj);
return obj; return obj;
} }
@ -517,7 +539,7 @@ cmXCodeObject*
cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type) cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
{ {
cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type); cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
this->XCodeObjects.push_back(obj); this->addObject(obj);
return obj; return obj;
} }
@ -2040,6 +2062,9 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
} }
} }
target->SetId(this->GetOrCreateId(
cmtarget.GetName(), target->GetId()).c_str());
return target; return target;
} }
@ -2188,6 +2213,8 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
target->AddAttribute("productType", this->CreateString(productType)); target->AddAttribute("productType", this->CreateString(productType));
} }
target->SetTarget(&cmtarget); target->SetTarget(&cmtarget);
target->SetId(this->GetOrCreateId(
cmtarget.GetName(), target->GetId()).c_str());
return target; return target;
} }
@ -2210,6 +2237,26 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
return 0; 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, void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
cmXCodeObject* dependTarget) cmXCodeObject* dependTarget)
@ -2739,6 +2786,12 @@ void cmGlobalXCodeGenerator
this->RootObject = this->CreateObject(cmXCodeObject::PBXProject); this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
this->RootObject->SetComment("Project object"); 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); group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
this->RootObject->AddAttribute("mainGroup", this->RootObject->AddAttribute("mainGroup",
this->CreateObjectReference(mainGroup)); this->CreateObjectReference(mainGroup));
@ -3137,6 +3190,11 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
} }
this->WriteXCodePBXProj(fout, root, generators); this->WriteXCodePBXProj(fout, root, generators);
this->ClearXCodeObjects(); 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*); cmXCodeObject* FindXCodeTarget(cmTarget*);
std::string GetOrCreateId(const char* name, const char* id);
// create cmXCodeObject from these functions so that memory can be managed // create cmXCodeObject from these functions so that memory can be managed
// correctly. All objects created are stored in this->XCodeObjects. // correctly. All objects created are stored in this->XCodeObjects.
cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype); cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype);
@ -197,9 +199,11 @@ protected:
unsigned int XcodeVersion; unsigned int XcodeVersion;
std::string VersionString; std::string VersionString;
std::set<cmStdString> XCodeObjectIDs;
std::vector<cmXCodeObject*> XCodeObjects; std::vector<cmXCodeObject*> XCodeObjects;
cmXCodeObject* RootObject; cmXCodeObject* RootObject;
private: private:
void addObject(cmXCodeObject *obj);
std::string PostBuildMakeTarget(std::string const& tName, std::string PostBuildMakeTarget(std::string const& tName,
std::string const& configName); std::string const& configName);
cmXCodeObject* MainGroupChildren; cmXCodeObject* MainGroupChildren;

View File

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

View File

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