diff -rU2 ../apa/cmake-2.8.3/Source/cmXCodeObject.cxx ./Source/cmXCodeObject.cxx
--- ../apa/cmake-2.8.3/Source/cmXCodeObject.cxx	2010-11-03 20:58:29.000000000 +0100
+++ ./Source/cmXCodeObject.cxx	2010-12-26 23:40:35.000000000 +0100
@@ -12,4 +12,5 @@
 #include "cmXCodeObject.h"
 #include "cmSystemTools.h"
+# include <cmsys/MD5.h>
 
 //----------------------------------------------------------------------------
@@ -42,31 +43,4 @@
   
   this->IsA = ptype;
-  if(type == OBJECT)
-    {
-    cmOStringStream str;
-    str << (void*)this;
-    str << (void*)this;
-    str << (void*)this;
-    this->Id = str.str();
-    }
-  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";
-      }
-    }
-  if(this->Id.size() > 24)
-    {
-    this->Id = this->Id.substr(0,24);
-    }
   this->TypeValue = type;
   if(this->TypeValue == OBJECT)
@@ -98,5 +72,5 @@
     }
   cmXCodeObject::Indent(2*indentFactor, out);
-  out << this->Id << " ";
+  out << this->GetId() << " ";
   if(!(this->IsA == PBXGroup && this->Comment.size() == 0))
     {
@@ -129,5 +103,5 @@
         {
         cmXCodeObject::Indent(4*indentFactor, out);
-        out << i->second->List[k]->Id << " ";
+        out << i->second->List[k]->GetId() << " ";
         i->second->List[k]->PrintComment(out);
         out << "," << separator;
@@ -181,5 +155,5 @@
     else if(object->TypeValue == OBJECT_REF)
       {
-      out << i->first << " = " << object->Object->Id;
+      out << i->first << " = " << object->Object->GetId();
       if(object->Object->HasComment() && i->first != "remoteGlobalIDString")
         {
@@ -222,4 +196,56 @@
 
 //----------------------------------------------------------------------------
+const char* cmXCodeObject::GetId()
+{
+  const char *id;
+  if(TypeValue != OBJECT) {
+    return "Temporary CMake object, should never be written to disk!";
+  }
+  
+  if(this->Id.length() != 0)
+    return this->Id.c_str();
+
+  switch(IsA) { 
+    //Generate a hashed IDs for these, so that x.pbxuser file can
+    //reference to them even after a project has been regenerated.
+    case PBXProject:
+    case PBXNativeTarget:
+    case PBXApplicationReference:
+    case PBXExecutableFileReference:
+    case PBXLibraryReference:
+    case PBXToolTarget:
+    case PBXLibraryTarget:
+    case PBXAggregateTarget:
+    {
+      cmXCodeObject *o = this->GetObject("name");
+      if(o){
+        id = o->GetString();
+      } else {
+        id = this->GetComment();
+      }
+      break;
+    }
+    default: {
+        cmOStringStream str;
+        str << (void*)this;
+        str << (void*)this;
+        str << (void*)this;
+        id = str.str().c_str();
+        break;
+      }
+  }
+  char md5[32];
+  cmsysMD5* sum = cmsysMD5_New();
+  cmsysMD5_Initialize(sum);
+  cmsysMD5_Append(sum, (const unsigned char*)id, strlen(id));
+  cmsysMD5_FinalizeHex(sum, md5);
+  cmsysMD5_Delete(sum);
+  
+  this->Id = cmSystemTools::UpperCase(md5);
+  this->Id = this->Id.substr(0,24);
+  return this->Id.c_str();
+}
+
+//----------------------------------------------------------------------------
 void cmXCodeObject::CopyAttributes(cmXCodeObject* copy)
 {
diff -rU2 ../apa/cmake-2.8.3/Source/cmXCodeObject.h ./Source/cmXCodeObject.h
--- ../apa/cmake-2.8.3/Source/cmXCodeObject.h	2010-11-03 20:58:29.000000000 +0100
+++ ./Source/cmXCodeObject.h	2010-12-26 23:40:51.000000000 +0100
@@ -14,4 +14,5 @@
 
 #include "cmStandardIncludes.h"
+
 class cmTarget;
 
@@ -80,8 +81,5 @@
   static void PrintList(std::vector<cmXCodeObject*> const&, 
                         std::ostream& out);
-  const char* GetId()
-    {
-      return this->Id.c_str();
-    }
+  const char* GetId();
   cmTarget* GetTarget()
     {
Only in .: build
