|  | @@ -19,6 +19,7 @@
 | 
	
		
			
				|  |  |  #include "cmComputeLinkInformation.h"
 | 
	
		
			
				|  |  |  #include "cmSourceFile.h"
 | 
	
		
			
				|  |  |  #include "cmCustomCommandGenerator.h"
 | 
	
		
			
				|  |  | +#include "cmGeneratorTarget.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include <cmsys/auto_ptr.hxx>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -303,6 +304,10 @@ void cmGlobalXCodeGenerator::Generate()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    this->ForceLinkerLanguages();
 | 
	
		
			
				|  |  |    this->cmGlobalGenerator::Generate();
 | 
	
		
			
				|  |  | +  if(cmSystemTools::GetErrorOccuredFlag())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |    for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      cmLocalGenerator* root = it->second[0];
 | 
	
	
		
			
				|  | @@ -417,6 +422,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
 | 
	
		
			
				|  |  |        // this will make sure that when the next target is built
 | 
	
		
			
				|  |  |        // things are up-to-date
 | 
	
		
			
				|  |  |        if((target.GetType() == cmTarget::EXECUTABLE ||
 | 
	
		
			
				|  |  | +// Nope - no post-build for OBJECT_LIRBRARY
 | 
	
		
			
				|  |  | +//          target.GetType() == cmTarget::OBJECT_LIBRARY ||
 | 
	
		
			
				|  |  |            target.GetType() == cmTarget::STATIC_LIBRARY ||
 | 
	
		
			
				|  |  |            target.GetType() == cmTarget::SHARED_LIBRARY ||
 | 
	
		
			
				|  |  |            target.GetType() == cmTarget::MODULE_LIBRARY))
 | 
	
	
		
			
				|  | @@ -570,14 +577,42 @@ cmXCodeObject* cmGlobalXCodeGenerator
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | -cmStdString GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
 | 
	
		
			
				|  |  | +cmStdString
 | 
	
		
			
				|  |  | +GetGroupMapKeyFromPath(cmTarget& cmtarget, const std::string& fullpath)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    cmStdString key(cmtarget.GetName());
 | 
	
		
			
				|  |  |    key += "-";
 | 
	
		
			
				|  |  | -  key += sf->GetFullPath();
 | 
	
		
			
				|  |  | +  key += fullpath;
 | 
	
		
			
				|  |  |    return key;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmStdString
 | 
	
		
			
				|  |  | +GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  return GetGroupMapKeyFromPath(cmtarget, sf->GetFullPath());
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmXCodeObject*
 | 
	
		
			
				|  |  | +cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
 | 
	
		
			
				|  |  | +  const std::string &fullpath,
 | 
	
		
			
				|  |  | +  cmTarget& cmtarget,
 | 
	
		
			
				|  |  | +  const std::string &lang)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  // Using a map and the full path guarantees that we will always get the same
 | 
	
		
			
				|  |  | +  // fileRef object for any given full path.
 | 
	
		
			
				|  |  | +  //
 | 
	
		
			
				|  |  | +  cmXCodeObject* fileRef =
 | 
	
		
			
				|  |  | +    this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
 | 
	
		
			
				|  |  | +  buildFile->SetComment(fileRef->GetComment());
 | 
	
		
			
				|  |  | +  buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return buildFile;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  |  cmXCodeObject*
 | 
	
		
			
				|  |  |  cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
 | 
	
	
		
			
				|  | @@ -612,14 +647,16 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
 | 
	
		
			
				|  |  |      flags += flagsBuild.GetString();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Using a map and the full path guarantees that we will always get the same
 | 
	
		
			
				|  |  | -  // fileRef object for any given full path.
 | 
	
		
			
				|  |  | -  //
 | 
	
		
			
				|  |  | -  cmXCodeObject* fileRef = this->CreateXCodeFileReference(sf, cmtarget);
 | 
	
		
			
				|  |  | +  const char* lang =
 | 
	
		
			
				|  |  | +    this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
 | 
	
		
			
				|  |  | +  if (!lang)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    lang = "";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
 | 
	
		
			
				|  |  | -  buildFile->SetComment(fileRef->GetComment());
 | 
	
		
			
				|  |  | -  buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
 | 
	
		
			
				|  |  | +  cmXCodeObject* buildFile =
 | 
	
		
			
				|  |  | +    this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang);
 | 
	
		
			
				|  |  | +  cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    cmXCodeObject* settings =
 | 
	
		
			
				|  |  |      this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
 | 
	
	
		
			
				|  | @@ -671,36 +708,12 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | -cmXCodeObject*
 | 
	
		
			
				|  |  | -cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
 | 
	
		
			
				|  |  | -                                                 cmTarget& cmtarget)
 | 
	
		
			
				|  |  | +std::string
 | 
	
		
			
				|  |  | +GetSourcecodeValueFromFileExtension(const std::string& _ext,
 | 
	
		
			
				|  |  | +                                    const std::string& lang)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  std::string fname = sf->GetFullPath();
 | 
	
		
			
				|  |  | -  cmXCodeObject* fileRef = this->FileRefs[fname];
 | 
	
		
			
				|  |  | -  if(!fileRef)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -    fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
 | 
	
		
			
				|  |  | -    std::string comment = fname;
 | 
	
		
			
				|  |  | -    //comment += " in ";
 | 
	
		
			
				|  |  | -    //std::string gname = group->GetObject("name")->GetString();
 | 
	
		
			
				|  |  | -    //comment += gname.substr(1, gname.size()-2);
 | 
	
		
			
				|  |  | -    fileRef->SetComment(fname.c_str());
 | 
	
		
			
				|  |  | -    this->FileRefs[fname] = fileRef;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  cmStdString key = GetGroupMapKey(cmtarget, sf);
 | 
	
		
			
				|  |  | -  cmXCodeObject* group = this->GroupMap[key];
 | 
	
		
			
				|  |  | -  cmXCodeObject* children = group->GetObject("children");
 | 
	
		
			
				|  |  | -  if (!children->HasObject(fileRef))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -    children->AddObject(fileRef);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  const char* lang =
 | 
	
		
			
				|  |  | -    this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
 | 
	
		
			
				|  |  | +  std::string ext = cmSystemTools::LowerCase(_ext);
 | 
	
		
			
				|  |  |    std::string sourcecode = "sourcecode";
 | 
	
		
			
				|  |  | -  std::string ext = sf->GetExtension();
 | 
	
		
			
				|  |  | -  ext = cmSystemTools::LowerCase(ext);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if(ext == "o")
 | 
	
		
			
				|  |  |      {
 | 
	
	
		
			
				|  | @@ -735,25 +748,25 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      sourcecode += ".cpp.h";
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  else if(lang && strcmp(lang, "CXX") == 0)
 | 
	
		
			
				|  |  | +  else if(ext == "png" || ext == "gif" || ext == "jpg")
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    sourcecode += ".cpp.cpp";
 | 
	
		
			
				|  |  | +    sourcecode = "image";
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  else if(lang && strcmp(lang, "C") == 0)
 | 
	
		
			
				|  |  | +  else if(ext == "txt")
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    sourcecode += ".c.c";
 | 
	
		
			
				|  |  | +    sourcecode += ".text";
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  else if(lang && strcmp(lang, "Fortran") == 0)
 | 
	
		
			
				|  |  | +  else if(lang == "CXX")
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    sourcecode += ".fortran.f90";
 | 
	
		
			
				|  |  | +    sourcecode += ".cpp.cpp";
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  else if(ext == "png" || ext == "gif" || ext == "jpg")
 | 
	
		
			
				|  |  | +  else if(lang == "C")
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    sourcecode = "image";
 | 
	
		
			
				|  |  | +    sourcecode += ".c.c";
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  else if(ext == "txt")
 | 
	
		
			
				|  |  | +  else if(lang == "Fortran")
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    sourcecode += ".text";
 | 
	
		
			
				|  |  | +    sourcecode += ".fortran.f90";
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    //else
 | 
	
		
			
				|  |  |    //  {
 | 
	
	
		
			
				|  | @@ -763,11 +776,51 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
 | 
	
		
			
				|  |  |    //  // valid lastKnownFileType value.
 | 
	
		
			
				|  |  |    //  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  return sourcecode;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmXCodeObject*
 | 
	
		
			
				|  |  | +cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
 | 
	
		
			
				|  |  | +  const std::string &fullpath,
 | 
	
		
			
				|  |  | +  cmTarget& cmtarget,
 | 
	
		
			
				|  |  | +  const std::string &lang)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  std::string fname = fullpath;
 | 
	
		
			
				|  |  | +  cmXCodeObject* fileRef = this->FileRefs[fname];
 | 
	
		
			
				|  |  | +  if(!fileRef)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
 | 
	
		
			
				|  |  | +    std::string comment = fname;
 | 
	
		
			
				|  |  | +    fileRef->SetComment(fname.c_str());
 | 
	
		
			
				|  |  | +    this->FileRefs[fname] = fileRef;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  cmStdString key = GetGroupMapKeyFromPath(cmtarget, fullpath);
 | 
	
		
			
				|  |  | +  cmXCodeObject* group = this->GroupMap[key];
 | 
	
		
			
				|  |  | +  cmXCodeObject* children = group->GetObject("children");
 | 
	
		
			
				|  |  | +  if (!children->HasObject(fileRef))
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    children->AddObject(fileRef);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Compute the extension.
 | 
	
		
			
				|  |  | +  std::string ext;
 | 
	
		
			
				|  |  | +  std::string realExt =
 | 
	
		
			
				|  |  | +    cmSystemTools::GetFilenameLastExtension(fullpath);
 | 
	
		
			
				|  |  | +  if(!realExt.empty())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    // Extension without the leading '.'.
 | 
	
		
			
				|  |  | +    ext = realExt.substr(1);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  std::string sourcecode = GetSourcecodeValueFromFileExtension(ext, lang);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    fileRef->AddAttribute("lastKnownFileType",
 | 
	
		
			
				|  |  |                          this->CreateString(sourcecode.c_str()));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Store the file path relative to the top of the source tree.
 | 
	
		
			
				|  |  | -  std::string path = this->RelativeToSource(sf->GetFullPath().c_str());
 | 
	
		
			
				|  |  | +  std::string path = this->RelativeToSource(fullpath.c_str());
 | 
	
		
			
				|  |  |    std::string name = cmSystemTools::GetFilenameName(path.c_str());
 | 
	
		
			
				|  |  |    const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())?
 | 
	
		
			
				|  |  |                              "<absolute>" : "SOURCE_ROOT");
 | 
	
	
		
			
				|  | @@ -781,6 +834,22 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
 | 
	
		
			
				|  |  |    return fileRef;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmXCodeObject*
 | 
	
		
			
				|  |  | +cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
 | 
	
		
			
				|  |  | +                                                 cmTarget& cmtarget)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  const char* lang =
 | 
	
		
			
				|  |  | +    this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
 | 
	
		
			
				|  |  | +  if (!lang)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    lang = "";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return this->CreateXCodeFileReferenceFromPath(
 | 
	
		
			
				|  |  | +    sf->GetFullPath(), cmtarget, lang);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  |  bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -889,6 +958,20 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // Add object library contents as external objects. (Equivalent to
 | 
	
		
			
				|  |  | +    // the externalObjFiles above, except each one is not a cmSourceFile
 | 
	
		
			
				|  |  | +    // within the target.)
 | 
	
		
			
				|  |  | +    std::vector<std::string> objs;
 | 
	
		
			
				|  |  | +    this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
 | 
	
		
			
				|  |  | +    for(std::vector<std::string>::const_iterator
 | 
	
		
			
				|  |  | +          oi = objs.begin(); oi != objs.end(); ++oi)
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +      std::string obj = *oi;
 | 
	
		
			
				|  |  | +      cmXCodeObject* xsf =
 | 
	
		
			
				|  |  | +        this->CreateXCodeSourceFileFromPath(obj, cmtarget, "");
 | 
	
		
			
				|  |  | +      externalObjFiles.push_back(xsf);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      // some build phases only apply to bundles and/or frameworks
 | 
	
		
			
				|  |  |      bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
 | 
	
		
			
				|  |  |      bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
 | 
	
	
		
			
				|  | @@ -1494,7 +1577,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 | 
	
		
			
				|  |  |    std::string defFlags;
 | 
	
		
			
				|  |  |    bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
 | 
	
		
			
				|  |  |                   (target.GetType() == cmTarget::MODULE_LIBRARY));
 | 
	
		
			
				|  |  | -  bool binary = ((target.GetType() == cmTarget::STATIC_LIBRARY) ||
 | 
	
		
			
				|  |  | +  bool binary = ((target.GetType() == cmTarget::OBJECT_LIBRARY) ||
 | 
	
		
			
				|  |  | +                 (target.GetType() == cmTarget::STATIC_LIBRARY) ||
 | 
	
		
			
				|  |  |                   (target.GetType() == cmTarget::EXECUTABLE) ||
 | 
	
		
			
				|  |  |                   shared);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1581,7 +1665,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    const char* linkFlagsProp = "LINK_FLAGS";
 | 
	
		
			
				|  |  | -  if(target.GetType() == cmTarget::STATIC_LIBRARY)
 | 
	
		
			
				|  |  | +  if(target.GetType() == cmTarget::OBJECT_LIBRARY ||
 | 
	
		
			
				|  |  | +     target.GetType() == cmTarget::STATIC_LIBRARY)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      linkFlagsProp = "STATIC_LIBRARY_FLAGS";
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -1635,11 +1720,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 | 
	
		
			
				|  |  |    std::string pnprefix;
 | 
	
		
			
				|  |  |    std::string pnbase;
 | 
	
		
			
				|  |  |    std::string pnsuffix;
 | 
	
		
			
				|  |  | -  target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Store the product name for all target types.
 | 
	
		
			
				|  |  | -  buildSettings->AddAttribute("PRODUCT_NAME",
 | 
	
		
			
				|  |  | -                              this->CreateString(pnbase.c_str()));
 | 
	
		
			
				|  |  | +  target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Set attributes to specify the proper name for the target.
 | 
	
		
			
				|  |  |    std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory();
 | 
	
	
		
			
				|  | @@ -1663,17 +1745,44 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 | 
	
		
			
				|  |  |                                    this->CreateString(pndir.c_str()));
 | 
	
		
			
				|  |  |        pndir = target.GetDirectory(configName);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      buildSettings->AddAttribute("EXECUTABLE_PREFIX",
 | 
	
		
			
				|  |  |                                  this->CreateString(pnprefix.c_str()));
 | 
	
		
			
				|  |  |      buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
 | 
	
		
			
				|  |  |                                  this->CreateString(pnsuffix.c_str()));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +  else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    pnprefix = "lib";
 | 
	
		
			
				|  |  | +    pnbase = target.GetName();
 | 
	
		
			
				|  |  | +    pnsuffix = ".a";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if(this->XcodeVersion >= 21)
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +      std::string pncdir = this->GetObjectsNormalDirectory(
 | 
	
		
			
				|  |  | +        this->CurrentProject, configName, &target);
 | 
	
		
			
				|  |  | +      buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
 | 
	
		
			
				|  |  | +                                  this->CreateString(pncdir.c_str()));
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +      buildSettings->AddAttribute("OBJROOT",
 | 
	
		
			
				|  |  | +                                  this->CreateString(pndir.c_str()));
 | 
	
		
			
				|  |  | +      pndir = this->GetObjectsNormalDirectory(
 | 
	
		
			
				|  |  | +        this->CurrentProject, configName, &target);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Store the product name for all target types.
 | 
	
		
			
				|  |  | +  buildSettings->AddAttribute("PRODUCT_NAME",
 | 
	
		
			
				|  |  | +                              this->CreateString(pnbase.c_str()));
 | 
	
		
			
				|  |  |    buildSettings->AddAttribute("SYMROOT",
 | 
	
		
			
				|  |  |                                this->CreateString(pndir.c_str()));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Handle settings for each target type.
 | 
	
		
			
				|  |  |    switch(target.GetType())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | +    case cmTarget::OBJECT_LIBRARY:
 | 
	
		
			
				|  |  |      case cmTarget::STATIC_LIBRARY:
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      buildSettings->AddAttribute("LIBRARY_STYLE",
 | 
	
	
		
			
				|  | @@ -2177,6 +2286,7 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    switch(cmtarget.GetType())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | +    case cmTarget::OBJECT_LIBRARY:
 | 
	
		
			
				|  |  |      case cmTarget::STATIC_LIBRARY:
 | 
	
		
			
				|  |  |        return "archive.ar";
 | 
	
		
			
				|  |  |      case cmTarget::MODULE_LIBRARY:
 | 
	
	
		
			
				|  | @@ -2200,6 +2310,7 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    switch(cmtarget.GetType())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | +    case cmTarget::OBJECT_LIBRARY:
 | 
	
		
			
				|  |  |      case cmTarget::STATIC_LIBRARY:
 | 
	
		
			
				|  |  |        return "com.apple.product-type.library.static";
 | 
	
		
			
				|  |  |      case cmTarget::MODULE_LIBRARY:
 | 
	
	
		
			
				|  | @@ -2257,7 +2368,17 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  std::string fullName = cmtarget.GetFullName(defConfig.c_str());
 | 
	
		
			
				|  |  | +  std::string fullName;
 | 
	
		
			
				|  |  | +  if(cmtarget.GetType() == cmTarget::OBJECT_LIBRARY)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    fullName = "lib";
 | 
	
		
			
				|  |  | +    fullName += cmtarget.GetName();
 | 
	
		
			
				|  |  | +    fullName += ".a";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    fullName = cmtarget.GetFullName(defConfig.c_str());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |    fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
 | 
	
		
			
				|  |  |    fileRef->AddAttribute("refType", this->CreateString("0"));
 | 
	
		
			
				|  |  |    fileRef->AddAttribute("sourceTree",
 | 
	
	
		
			
				|  | @@ -2462,7 +2583,8 @@ void cmGlobalXCodeGenerator
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Skip link information for static libraries.
 | 
	
		
			
				|  |  | -  if(cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
 | 
	
		
			
				|  |  | +  if(cmtarget->GetType() == cmTarget::OBJECT_LIBRARY ||
 | 
	
		
			
				|  |  | +     cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      return;
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -2610,6 +2732,7 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        std::vector<cmSourceFile*>  classes = cmtarget.GetSourceFiles();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +      // Put cmSourceFile instances in proper groups:
 | 
	
		
			
				|  |  |        for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
 | 
	
		
			
				|  |  |            s != classes.end(); s++)
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -2623,6 +2746,21 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
 | 
	
		
			
				|  |  |          cmStdString key = GetGroupMapKey(cmtarget, sf);
 | 
	
		
			
				|  |  |          this->GroupMap[key] = pbxgroup;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // Put OBJECT_LIBRARY objects in proper groups:
 | 
	
		
			
				|  |  | +      std::vector<std::string> objs;
 | 
	
		
			
				|  |  | +      this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
 | 
	
		
			
				|  |  | +      for(std::vector<std::string>::const_iterator
 | 
	
		
			
				|  |  | +            oi = objs.begin(); oi != objs.end(); ++oi)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +        std::string const& source = *oi;
 | 
	
		
			
				|  |  | +        cmSourceGroup& sourceGroup =
 | 
	
		
			
				|  |  | +          mf->FindSourceGroup(source.c_str(), sourceGroups);
 | 
	
		
			
				|  |  | +        cmXCodeObject* pbxgroup =
 | 
	
		
			
				|  |  | +          this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
 | 
	
		
			
				|  |  | +        cmStdString key = GetGroupMapKeyFromPath(cmtarget, source);
 | 
	
		
			
				|  |  | +        this->GroupMap[key] = pbxgroup;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -3054,6 +3192,26 @@ void cmGlobalXCodeGenerator
 | 
	
		
			
				|  |  |    this->RootObject->AddAttribute("targets", allTargets);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +std::string
 | 
	
		
			
				|  |  | +cmGlobalXCodeGenerator::GetObjectsNormalDirectory(
 | 
	
		
			
				|  |  | +  const std::string &projName,
 | 
	
		
			
				|  |  | +  const std::string &configName,
 | 
	
		
			
				|  |  | +  const cmTarget *t) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  std::string dir =
 | 
	
		
			
				|  |  | +    t->GetMakefile()->GetCurrentOutputDirectory();
 | 
	
		
			
				|  |  | +  dir += "/";
 | 
	
		
			
				|  |  | +  dir += projName;
 | 
	
		
			
				|  |  | +  dir += ".build/";
 | 
	
		
			
				|  |  | +  dir += configName;
 | 
	
		
			
				|  |  | +  dir += "/";
 | 
	
		
			
				|  |  | +  dir += t->GetName();
 | 
	
		
			
				|  |  | +  dir += ".build/Objects-normal/";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return dir;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  |  void
 | 
	
		
			
				|  |  |  cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
 | 
	
	
		
			
				|  | @@ -3123,6 +3281,8 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
 | 
	
		
			
				|  |  |        cmTarget* t =target->GetTarget();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        if(t->GetType() == cmTarget::EXECUTABLE ||
 | 
	
		
			
				|  |  | +// Nope - no post-build for OBJECT_LIRBRARY
 | 
	
		
			
				|  |  | +//         t->GetType() == cmTarget::OBJECT_LIBRARY ||
 | 
	
		
			
				|  |  |           t->GetType() == cmTarget::STATIC_LIBRARY ||
 | 
	
		
			
				|  |  |           t->GetType() == cmTarget::SHARED_LIBRARY ||
 | 
	
		
			
				|  |  |           t->GetType() == cmTarget::MODULE_LIBRARY)
 | 
	
	
		
			
				|  | @@ -3178,15 +3338,8 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
 | 
	
		
			
				|  |  |          // then remove those exectuables as well
 | 
	
		
			
				|  |  |          if(this->Architectures.size() > 1)
 | 
	
		
			
				|  |  |            {
 | 
	
		
			
				|  |  | -          std::string universal =
 | 
	
		
			
				|  |  | -            t->GetMakefile()->GetCurrentOutputDirectory();
 | 
	
		
			
				|  |  | -          universal += "/";
 | 
	
		
			
				|  |  | -          universal += this->CurrentProject;
 | 
	
		
			
				|  |  | -          universal += ".build/";
 | 
	
		
			
				|  |  | -          universal += configName;
 | 
	
		
			
				|  |  | -          universal += "/";
 | 
	
		
			
				|  |  | -          universal += t->GetName();
 | 
	
		
			
				|  |  | -          universal += ".build/Objects-normal/";
 | 
	
		
			
				|  |  | +          std::string universal = this->GetObjectsNormalDirectory(
 | 
	
		
			
				|  |  | +            this->CurrentProject, configName, t);
 | 
	
		
			
				|  |  |            for( std::vector<std::string>::iterator arch =
 | 
	
		
			
				|  |  |                   this->Architectures.begin();
 | 
	
		
			
				|  |  |                 arch != this->Architectures.end(); ++arch)
 | 
	
	
		
			
				|  | @@ -3292,7 +3445,7 @@ cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | -const char* cmGlobalXCodeGenerator::GetCMakeCFGInitDirectory()
 | 
	
		
			
				|  |  | +const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    return this->XcodeVersion >= 21 ?
 | 
	
		
			
				|  |  |      "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
 | 
	
	
		
			
				|  | @@ -3545,3 +3698,51 @@ bool cmGlobalXCodeGenerator::IsMultiConfig()
 | 
	
		
			
				|  |  |    // Newer Xcode versions are multi config:
 | 
	
		
			
				|  |  |    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +cmGlobalXCodeGenerator
 | 
	
		
			
				|  |  | +::ComputeTargetObjects(cmGeneratorTarget* gt) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  // Count the number of object files with each name. Warn about duplicate
 | 
	
		
			
				|  |  | +  // names since Xcode names them uniquely automatically with a numeric suffix
 | 
	
		
			
				|  |  | +  // to avoid exact duplicate file names. Note that Mac file names are not
 | 
	
		
			
				|  |  | +  // typically case sensitive, hence the LowerCase.
 | 
	
		
			
				|  |  | +  std::map<cmStdString, int> counts;
 | 
	
		
			
				|  |  | +  for(std::vector<cmSourceFile*>::const_iterator
 | 
	
		
			
				|  |  | +      si = gt->ObjectSources.begin();
 | 
	
		
			
				|  |  | +      si != gt->ObjectSources.end(); ++si)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    cmSourceFile* sf = *si;
 | 
	
		
			
				|  |  | +    std::string objectName =
 | 
	
		
			
				|  |  | +      cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
 | 
	
		
			
				|  |  | +    objectName += ".o";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::string objectNameLower = cmSystemTools::LowerCase(objectName);
 | 
	
		
			
				|  |  | +    counts[objectNameLower] += 1;
 | 
	
		
			
				|  |  | +    if (2 == counts[objectNameLower])
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +      // TODO: emit warning about duplicate name?
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    gt->Objects[sf] = objectName;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const char* configName = this->GetCMakeCFGIntDir();
 | 
	
		
			
				|  |  | +  std::string dir = this->GetObjectsNormalDirectory(
 | 
	
		
			
				|  |  | +    this->CurrentProject, configName, gt->Target);
 | 
	
		
			
				|  |  | +  if(this->XcodeVersion >= 21)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    dir += "$(CURRENT_ARCH)/";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +#ifdef __ppc__
 | 
	
		
			
				|  |  | +    dir += "ppc/";
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef __i386
 | 
	
		
			
				|  |  | +    dir += "i386/";
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  gt->ObjectDirectory = dir;
 | 
	
		
			
				|  |  | +}
 |