/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmGlobalXCodeGenerator.h"
#include "cmLocalXCodeGenerator.h"
#include "cmMakefile.h"
#include "cmXCodeObject.h"
#include "cmXCode21Object.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
#include "cmComputeLinkInformation.h"
#include "cmSourceFile.h"

#include <cmsys/auto_ptr.hxx>

//----------------------------------------------------------------------------
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmXMLParser.h"

// parse the xml file storing the installed version of Xcode on
// the machine
class cmXcodeVersionParser : public cmXMLParser
{
public:
  cmXcodeVersionParser(): Version("1.5") {}
  void StartElement(const char* , const char** )
    {
      this->Data = "";
    }
  void EndElement(const char* name)
    {
      if(strcmp(name, "key") == 0)
        {
        this->Key = this->Data;
        }
      else if(strcmp(name, "string") == 0)
        {
        if(this->Key == "CFBundleShortVersionString")
          {
          this->Version = this->Data;
          }
        }
    }
  void CharacterDataHandler(const char* data, int length)
    {
      this->Data.append(data, length);
    }
  std::string Version;
  std::string Key;
  std::string Data;
};
#endif

// Builds either an object list or a space-separated string from the
// given inputs.
class cmGlobalXCodeGenerator::BuildObjectListOrString
{
  cmGlobalXCodeGenerator *Generator;
  cmXCodeObject *Group;
  bool Empty;
  std::string String;

public:
  BuildObjectListOrString(cmGlobalXCodeGenerator *gen, bool buildObjectList)
    : Generator(gen), Group(0), Empty(true)
    {
    if (buildObjectList)
      {
      this->Group = this->Generator->CreateObject(cmXCodeObject::OBJECT_LIST);
      }
    }

  bool IsEmpty() const { return this->Empty; }

  void Add(const char *newString)
    {
    this->Empty = false;

    if (this->Group)
      {
      this->Group->AddObject(this->Generator->CreateString(newString));
      }
    else
      {
      this->String += newString;
      this->String += ' ';
      }
    }

  const std::string &GetString() const { return this->String; }

  cmXCodeObject *CreateList()
    {
    if (this->Group)
      {
      return this->Group;
      }
    else
      {
      return this->Generator->CreateString(this->String.c_str());
      }
    }
};

//----------------------------------------------------------------------------
cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
{
  this->VersionString = version;

  // Compute an integer form of the version number.
  unsigned int v[2] = {0,0};
  sscanf(this->VersionString.c_str(), "%u.%u", &v[0], &v[1]);
  this->XcodeVersion = 10*v[0] + v[1];

  this->FindMakeProgramFile = "CMakeFindXCode.cmake";
  this->RootObject = 0;
  this->MainGroupChildren = 0;
  this->SourcesGroupChildren = 0;
  this->ResourcesGroupChildren = 0;
  this->CurrentMakefile = 0;
  this->CurrentLocalGenerator = 0;
}

//----------------------------------------------------------------------------
cmGlobalGenerator* cmGlobalXCodeGenerator::New()
{ 
#if defined(CMAKE_BUILD_WITH_CMAKE)  
  cmXcodeVersionParser parser;
  parser.ParseFile
    ("/Developer/Applications/Xcode.app/Contents/version.plist");
  cmsys::auto_ptr<cmGlobalXCodeGenerator>
    gg(new cmGlobalXCodeGenerator(parser.Version));
  if (gg->XcodeVersion == 20)
    {
    cmSystemTools::Message("Xcode 2.0 not really supported by cmake, "
                           "using Xcode 15 generator\n");
    gg->XcodeVersion = 15;
    }
  return gg.release();
#else
  std::cerr << "CMake should be built with cmake to use XCode, "
    "default to Xcode 1.5\n";
  return new cmGlobalXCodeGenerator;
#endif
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
                                            lang,
                                            cmMakefile * mf, bool optional)
{ 
  mf->AddDefinition("XCODE","1");
  mf->AddDefinition("XCODE_VERSION", this->VersionString.c_str());
  if(this->XcodeVersion == 15)
    {
    }
  else
    {
    mf->AddCacheDefinition(
      "CMAKE_CONFIGURATION_TYPES",
      "Debug;Release;MinSizeRel;RelWithDebInfo",
      "Semicolon separated list of supported configuration types, "
      "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
      "anything else will be ignored.",
      cmCacheManager::STRING);
    }
  mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc");
  mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++");
  mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
  // initialize Architectures so it can be used by 
  //  GetTargetObjectFileDirectories
  this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
    const char* osxArch = 
      mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
  const char* sysroot = 
      mf->GetDefinition("CMAKE_OSX_SYSROOT");
  if(osxArch && sysroot)
    {
    this->Architectures.clear();
    cmSystemTools::ExpandListArgument(std::string(osxArch),
                                      this->Architectures);
    }
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator
::GenerateBuildCommand(const char* makeProgram,
                       const char *projectName, 
                       const char* additionalOptions, 
                       const char *targetName,
                       const char* config, 
                       bool ignoreErrors,
                       bool)
{
  // Config is not used yet
  (void) ignoreErrors;

  // now build the test
  if(makeProgram == 0 || !strlen(makeProgram))
    {
    cmSystemTools::Error(
      "Generator cannot find the appropriate make command.");
    return "";
    }
  std::string makeCommand = 
    cmSystemTools::ConvertToOutputPath(makeProgram);
  std::string lowerCaseCommand = makeCommand;
  cmSystemTools::LowerCase(lowerCaseCommand);

  makeCommand += " -project ";
  makeCommand += projectName;
  makeCommand += ".xcode";
  if(this->XcodeVersion > 20)
    {
    makeCommand += "proj";
    }

  bool clean = false;
  if ( targetName && strcmp(targetName, "clean") == 0 )
    {
    clean = true;
    targetName = "ALL_BUILD";
    }
  if(clean)
    {
    makeCommand += " clean";
    }
  else
    {
    makeCommand += " build";
    }
  makeCommand += " -target ";
  // if it is a null string for config don't use it
  if(config && *config == 0)
    {
    config = 0;
    }
  if (targetName && strlen(targetName))
    {
    makeCommand += targetName;
    }
  else
    {
    makeCommand += "ALL_BUILD";
    }
  if(this->XcodeVersion == 15)
    {
    makeCommand += " -buildstyle Development ";
    }
  else
    {
    makeCommand += " -configuration ";
    makeCommand += config?config:"Debug";
    }
  if ( additionalOptions )
    {
    makeCommand += " ";
    makeCommand += additionalOptions;
    }
  return makeCommand;
}

//----------------------------------------------------------------------------
///! Create a local generator appropriate to this Global Generator
cmLocalGenerator *cmGlobalXCodeGenerator::CreateLocalGenerator()
{
  cmLocalGenerator *lg = new cmLocalXCodeGenerator;
  lg->SetGlobalGenerator(this);
  return lg;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::Generate()
{
  std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
  // make sure extra targets are added before calling
  // the parent generate which will call trace depends
  for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
    { 
    cmLocalGenerator* root = it->second[0];
    this->SetGenerationRoot(root);
    // add ALL_BUILD, INSTALL, etc
    this->AddExtraTargets(root, it->second);
    }
  this->ForceLinkerLanguages();
  this->cmGlobalGenerator::Generate();
  for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
    { 
    cmLocalGenerator* root = it->second[0];
    this->SetGenerationRoot(root);
    // now create the project
    this->OutputXCodeProject(root, it->second);
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
{
  this->CurrentProject = root->GetMakefile()->GetProjectName();
  this->SetCurrentLocalGenerator(root);
  cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentDirectory(),
                           this->ProjectSourceDirectoryComponents);
  cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentOutputDirectory(),
                           this->ProjectOutputDirectoryComponents);

  this->CurrentXCodeHackMakefile =
    root->GetMakefile()->GetCurrentOutputDirectory();
  this->CurrentXCodeHackMakefile += "/CMakeScripts";
  cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile.c_str());
  this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
}

//----------------------------------------------------------------------------
void 
cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, 
                                        std::vector<cmLocalGenerator*>& gens)
{
  cmMakefile* mf = root->GetMakefile();

  // Add ALL_BUILD
  const char* no_working_directory = 0;
  std::vector<std::string> no_depends;
  mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
                        no_working_directory,
                        "echo", "Build all projects");
  cmTarget* allbuild = mf->FindTarget("ALL_BUILD");

  // Refer to the main build configuration file for easy editing.
  std::string listfile = mf->GetStartDirectory();
  listfile += "/";
  listfile += "CMakeLists.txt";
  allbuild->AddSource(listfile.c_str());

  // Add XCODE depend helper 
  std::string dir = mf->GetCurrentOutputDirectory();
  cmCustomCommandLine makecommand;
  makecommand.push_back("make");
  makecommand.push_back("-C");
  makecommand.push_back(dir.c_str());
  makecommand.push_back("-f");
  makecommand.push_back(this->CurrentXCodeHackMakefile.c_str());
  if(this->XcodeVersion > 20)
    {
    makecommand.push_back("all.$(CONFIGURATION)");
    }
  cmCustomCommandLines commandLines;
  commandLines.push_back(makecommand);
  // Add Re-Run CMake rules
  this->CreateReRunCMakeFile(root);

  // now make the allbuild depend on all the non-utility targets
  // in the project
  for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
      i != gens.end(); ++i)
    {
    cmLocalGenerator* lg = *i; 
    if(this->IsExcluded(root, *i))
      {
      continue;
      }
    cmTargets& tgts = lg->GetMakefile()->GetTargets();
    for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
      {
      cmTarget& target = l->second;
      // make all exe, shared libs and modules 
      // run the depend check makefile as a post build rule
      // this will make sure that when the next target is built
      // things are up-to-date
      if((target.GetType() == cmTarget::EXECUTABLE ||
          target.GetType() == cmTarget::STATIC_LIBRARY ||
          target.GetType() == cmTarget::SHARED_LIBRARY ||
          target.GetType() == cmTarget::MODULE_LIBRARY))
        {
        lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
                                                    no_depends,
                                                    commandLines,
                                                    cmTarget::POST_BUILD,
                                                    "Depend check for xcode",
                                                    dir.c_str());
                                                    
        }
      if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
        {
        allbuild->AddUtility(target.GetName());
        }

      // Refer to the build configuration file for easy editing.
      listfile = lg->GetMakefile()->GetStartDirectory();
      listfile += "/";
      listfile += "CMakeLists.txt";
      target.AddSource(listfile.c_str());
      }
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateReRunCMakeFile(cmLocalGenerator* root)
{
  cmMakefile* mf = root->GetMakefile();
  std::vector<std::string> lfiles = mf->GetListFiles();
  // sort the array
  std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>()); 
  std::vector<std::string>::iterator new_end = 
    std::unique(lfiles.begin(), lfiles.end());
  lfiles.erase(new_end, lfiles.end());
  std::string dir = mf->GetHomeOutputDirectory();
  this->CurrentReRunCMakeMakefile = dir;
  this->CurrentReRunCMakeMakefile += "/CMakeScripts";
  cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str());
  this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
  cmGeneratedFileStream makefileStream
    (this->CurrentReRunCMakeMakefile.c_str());
  makefileStream.SetCopyIfDifferent(true);
  makefileStream << "# Generated by CMake, DO NOT EDIT\n";
  makefileStream << cmake::GetCMakeFilesDirectoryPostSlash();
  makefileStream << "cmake.check_cache: ";
  for(std::vector<std::string>::const_iterator i = lfiles.begin();
      i !=  lfiles.end(); ++i)
    {
    makefileStream << "\\\n" << this->ConvertToRelativeForMake(i->c_str());
    }
  std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
  makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str()) 
                 << " -H" << this->ConvertToRelativeForMake(
                   mf->GetHomeDirectory())
                 << " -B" << this->ConvertToRelativeForMake(
                   mf->GetHomeOutputDirectory()) << "\n";
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ClearXCodeObjects()
{
  this->TargetDoneSet.clear();
  for(unsigned int i = 0; i < this->XCodeObjects.size(); ++i)
    {
    delete this->XCodeObjects[i];
    }
  this->XCodeObjects.clear();
  this->GroupMap.clear();
  this->GroupNameMap.clear();
  this->TargetGroup.clear();
  this->FileRefs.clear();
}

//----------------------------------------------------------------------------
cmXCodeObject* 
cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
{
  cmXCodeObject* obj;
  if(this->XcodeVersion == 15)
    {
    obj = new cmXCodeObject(ptype, cmXCodeObject::OBJECT);
    }
  else
    {
    obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
    }
  this->XCodeObjects.push_back(obj);
  return obj;
}

//----------------------------------------------------------------------------
cmXCodeObject* 
cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
{
  cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
  this->XCodeObjects.push_back(obj);
  return obj;
}

//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateString(const char* s)
{
  cmXCodeObject* obj = this->CreateObject(cmXCodeObject::STRING);
  obj->SetString(s);
  return obj;
}

//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator
::CreateObjectReference(cmXCodeObject* ref)
{
  cmXCodeObject* obj = this->CreateObject(cmXCodeObject::OBJECT_REF);
  obj->SetObject(ref);
  return obj;
}

//----------------------------------------------------------------------------
cmStdString GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
{
  cmStdString key(cmtarget.GetName());
  key += "-";
  key += sf->GetFullPath();
  return key;
}

//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
                                              cmSourceFile* sf,
                                              cmTarget& cmtarget)
{
  // Add flags from target and source file properties.
  std::string flags;
  if(cmtarget.GetProperty("COMPILE_FLAGS"))
    {
    lg->AppendFlags(flags, cmtarget.GetProperty("COMPILE_FLAGS"));
    }
  lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS"));

  // Add per-source definitions.
  BuildObjectListOrString flagsBuild(this, false);
  this->AppendDefines(flagsBuild,
                      sf->GetProperty("COMPILE_DEFINITIONS"), true);
  if (!flagsBuild.IsEmpty())
    {
    if (flags.size())
      {
      flags += ' ';
      }
    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);

  cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
  buildFile->SetComment(fileRef->GetComment());
  buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));

  cmXCodeObject* settings = 
    this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
  settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags.c_str()));

  // Is this a resource file in this target? Add it to the resources group...
  //
  cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
  bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);

  // Is this a "private" or "public" framework header file?
  // Set the ATTRIBUTES attribute appropriately...
  //
  if(cmtarget.IsFrameworkOnApple())
    {
    if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
      {
      cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
      attrs->AddObject(this->CreateString("Private"));
      settings->AddAttribute("ATTRIBUTES", attrs);
      isResource = true;
      }
    else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
      {
      cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
      attrs->AddObject(this->CreateString("Public"));
      settings->AddAttribute("ATTRIBUTES", attrs);
      isResource = true;
      }
    }

  // Add the fileRef to the top level Resources group/folder if it is not
  // already there.
  //
  if(isResource && this->ResourcesGroupChildren &&
    !this->ResourcesGroupChildren->HasObject(fileRef))
    {
    this->ResourcesGroupChildren->AddObject(fileRef);
    }

  buildFile->AddAttribute("settings", settings);
  return buildFile;
}

//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
                                                 cmTarget& cmtarget)
{
  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 sourcecode = "sourcecode";
  std::string ext = sf->GetExtension();
  ext = cmSystemTools::LowerCase(ext);

  if(ext == "o")
    {
    sourcecode = "compiled.mach-o.objfile";
    }
  else if(ext == "xib")
    {
    sourcecode = "file.xib";
    }
  else if(ext == "mm")
    {
    sourcecode += ".cpp.objcpp";
    }
  else if(ext == "m")
    {
    sourcecode += ".c.objc";
    }
  else if(ext == "xib")
    {
    sourcecode += ".file.xib";
    }
  else if(ext == "plist")
    {
    sourcecode += ".text.plist";
    }
  else if(ext == "h")
    {
    sourcecode += ".c.h";
    }
  else if(ext == "hxx" || ext == "hpp" || ext == "txx"
    || ext == "pch")
    {
    sourcecode += ".cpp.h";
    }
  else if(lang && strcmp(lang, "CXX") == 0)
    {
    sourcecode += ".cpp.cpp";
    }
  else if(lang && strcmp(lang, "C") == 0)
    {
    sourcecode += ".c.c";
    }
  else if(lang && strcmp(lang, "Fortran") == 0)
    {
    sourcecode += ".fortran.f90";
    }
  else if(ext == "png" || ext == "gif" || ext == "jpg")
    {
    sourcecode = "image";
    }
  else if(ext == "txt")
    {
    sourcecode += ".text";
    }
  //else
  //  {
  //  // Already specialized above or we leave sourcecode == "sourcecode"
  //  // which is probably the most correct choice. Extensionless headers,
  //  // for example... Or file types unknown to Xcode that do not map to a
  //  // valid lastKnownFileType value.
  //  }

  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 name = cmSystemTools::GetFilenameName(path.c_str());
  const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())?
                            "<absolute>" : "SOURCE_ROOT");
  fileRef->AddAttribute("name", this->CreateString(name.c_str()));
  fileRef->AddAttribute("path", this->CreateString(path.c_str()));
  fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
  if(this->XcodeVersion == 15)
    {
    fileRef->AddAttribute("refType", this->CreateString("4"));
    }
  return fileRef;
}

//----------------------------------------------------------------------------
bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
{
  if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
     tname == "install" || tname == "package" || tname == "RUN_TESTS" )
    {
    if(this->TargetDoneSet.find(tname) != this->TargetDoneSet.end())
      {
      return true;
      }
    this->TargetDoneSet.insert(tname);
    return false;
    }
  return false;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
{
  this->CurrentLocalGenerator = gen;
  this->CurrentMakefile = gen->GetMakefile();
  std::string outdir =
    cmSystemTools::CollapseFullPath(this->CurrentMakefile->
                                    GetCurrentOutputDirectory());
  cmSystemTools::SplitPath(outdir.c_str(), 
                           this->CurrentOutputDirectoryComponents);

  // Select the current set of configuration types.
  this->CurrentConfigurationTypes.clear();
  if(this->XcodeVersion > 20)
    {
    if(const char* types =
       this->CurrentMakefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
      {
      cmSystemTools::ExpandListArgument(types, 
                                        this->CurrentConfigurationTypes);
      }
    }
  if(this->CurrentConfigurationTypes.empty())
    {
    if(const char* buildType =
       this->CurrentMakefile->GetDefinition("CMAKE_BUILD_TYPE"))
      {
      this->CurrentConfigurationTypes.push_back(buildType);
      }
    else
      {
      this->CurrentConfigurationTypes.push_back("");
      }
    }
}

//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
                                           std::vector<cmXCodeObject*>&
                                           targets)
{
  this->SetCurrentLocalGenerator(gen);
  cmTargets &tgts = this->CurrentMakefile->GetTargets();
  for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
    {
    cmTarget& cmtarget = l->second;

    // make sure ALL_BUILD, INSTALL, etc are only done once
    if(this->SpecialTargetEmitted(l->first.c_str()))
      {
      continue;
      }

    if(cmtarget.GetType() == cmTarget::UTILITY ||
       cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
      {
      targets.push_back(this->CreateUtilityTarget(cmtarget));
      continue;
      }

    // organize the sources
    std::vector<cmSourceFile*> const &classes = cmtarget.GetSourceFiles();
    std::vector<cmXCodeObject*> externalObjFiles;
    std::vector<cmXCodeObject*> headerFiles;
    std::vector<cmXCodeObject*> resourceFiles;
    std::vector<cmXCodeObject*> sourceFiles;
    for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
        i != classes.end(); ++i)
      {
      cmXCodeObject* xsf =
        this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
                                    *i, cmtarget);
      cmXCodeObject* fr = xsf->GetObject("fileRef");
      cmXCodeObject* filetype = 
        fr->GetObject()->GetObject("lastKnownFileType");

      cmTarget::SourceFileFlags tsFlags =
        cmtarget.GetTargetSourceFileFlags(*i);

      if(strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
        {
        externalObjFiles.push_back(xsf);
        }
      else if(this->IsHeaderFile(*i) ||
        (tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
        (tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
        {
        headerFiles.push_back(xsf);
        }
      else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
        {
        resourceFiles.push_back(xsf);
        }
      else if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
        {
        // Include this file in the build if it has a known language
        // and has not been listed as an ignored extension for this
        // generator.
        if(this->CurrentLocalGenerator->GetSourceFileLanguage(**i) &&
           !this->IgnoreFile((*i)->GetExtension().c_str()))
          {
          sourceFiles.push_back(xsf);
          }
        }
      }

    // some build phases only apply to bundles and/or frameworks
    bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
    bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");

    cmXCodeObject* buildFiles = 0;

    // create source build phase
    cmXCodeObject* sourceBuildPhase = 0;
    if (!sourceFiles.empty())
      {
      sourceBuildPhase =
        this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase);
      sourceBuildPhase->SetComment("Sources");
      sourceBuildPhase->AddAttribute("buildActionMask", 
                                     this->CreateString("2147483647"));
      buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
      for(std::vector<cmXCodeObject*>::iterator i = sourceFiles.begin();
          i != sourceFiles.end(); ++i)
        {
        buildFiles->AddObject(*i);
        }
      sourceBuildPhase->AddAttribute("files", buildFiles);
      sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
                                     this->CreateString("0"));
      }

    // create header build phase - only for framework targets
    cmXCodeObject* headerBuildPhase = 0;
    if (!headerFiles.empty() && isFrameworkTarget)
      {
      headerBuildPhase =
        this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase);
      headerBuildPhase->SetComment("Headers");
      headerBuildPhase->AddAttribute("buildActionMask",
                                     this->CreateString("2147483647"));
      buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
      for(std::vector<cmXCodeObject*>::iterator i = headerFiles.begin();
          i != headerFiles.end(); ++i)
        {
        buildFiles->AddObject(*i);
        }
      headerBuildPhase->AddAttribute("files", buildFiles);
      headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
                                     this->CreateString("0"));
      }

    // create resource build phase - only for framework or bundle targets
    cmXCodeObject* resourceBuildPhase = 0;
    if (!resourceFiles.empty() && (isFrameworkTarget || isBundleTarget))
      {
      resourceBuildPhase =
        this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase);
      resourceBuildPhase->SetComment("Resources");
      resourceBuildPhase->AddAttribute("buildActionMask",
                                       this->CreateString("2147483647"));
      buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
      for(std::vector<cmXCodeObject*>::iterator i = resourceFiles.begin();
          i != resourceFiles.end(); ++i)
        {
        buildFiles->AddObject(*i);
        }
      resourceBuildPhase->AddAttribute("files", buildFiles);
      resourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
                                     this->CreateString("0"));
      }

    // create vector of "non-resource content file" build phases - only for
    // framework or bundle targets
    std::vector<cmXCodeObject*> contentBuildPhases;
    if (isFrameworkTarget || isBundleTarget)
      {
      typedef std::map<cmStdString, std::vector<cmSourceFile*> >
        mapOfVectorOfSourceFiles;
      mapOfVectorOfSourceFiles bundleFiles;
      for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
          i != classes.end(); ++i)
        {
        cmTarget::SourceFileFlags tsFlags =
          cmtarget.GetTargetSourceFileFlags(*i);
        if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
          {
          bundleFiles[tsFlags.MacFolder].push_back(*i);
          }
        }
      mapOfVectorOfSourceFiles::iterator mit;
      for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit )
        {
        cmXCodeObject* copyFilesBuildPhase =
          this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
        copyFilesBuildPhase->SetComment("Copy files");
        copyFilesBuildPhase->AddAttribute("buildActionMask",
          this->CreateString("2147483647"));
        copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
          this->CreateString("6"));
        cmOStringStream ostr;
        if (cmtarget.IsFrameworkOnApple())
          {
          // dstPath in frameworks is relative to Versions/<version>
          ostr << mit->first;
          }
        else if ( mit->first != "MacOS" )
          {
          // dstPath in bundles is relative to Contents/MacOS
          ostr << "../" << mit->first.c_str();
          }
        copyFilesBuildPhase->AddAttribute("dstPath",
          this->CreateString(ostr.str().c_str()));
        copyFilesBuildPhase->AddAttribute(
          "runOnlyForDeploymentPostprocessing", this->CreateString("0"));
        buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
        copyFilesBuildPhase->AddAttribute("files", buildFiles);
        std::vector<cmSourceFile*>::iterator sfIt;
        for ( sfIt = mit->second.begin(); sfIt != mit->second.end(); ++ sfIt )
          {
          cmXCodeObject* xsf =
            this->CreateXCodeSourceFile(this->CurrentLocalGenerator, 
                                        *sfIt, cmtarget);
          buildFiles->AddObject(xsf);
          }
        contentBuildPhases.push_back(copyFilesBuildPhase);
        }
      }

    // create framework build phase
    cmXCodeObject* frameworkBuildPhase = 0;
    if (!externalObjFiles.empty())
      {
      frameworkBuildPhase =
        this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
      frameworkBuildPhase->SetComment("Frameworks");
      frameworkBuildPhase->AddAttribute("buildActionMask",
                                        this->CreateString("2147483647"));
      buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
      frameworkBuildPhase->AddAttribute("files", buildFiles);
      for(std::vector<cmXCodeObject*>::iterator i =  externalObjFiles.begin();
          i != externalObjFiles.end(); ++i)
        {
        buildFiles->AddObject(*i);
        }
      frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
                                        this->CreateString("0"));
      }

    // create list of build phases and create the XCode target
    cmXCodeObject* buildPhases = 
      this->CreateObject(cmXCodeObject::OBJECT_LIST);

    this->CreateCustomCommands(buildPhases, sourceBuildPhase,
                               headerBuildPhase, resourceBuildPhase,
                               contentBuildPhases,
                               frameworkBuildPhase, cmtarget);

    targets.push_back(this->CreateXCodeTarget(cmtarget, buildPhases));
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ForceLinkerLanguages()
{
  // This makes sure all targets link using the proper language.
  for(std::map<cmStdString, cmTarget*>::const_iterator
        ti = this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
    {
    this->ForceLinkerLanguage(*ti->second);
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
{
  // This matters only for targets that link.
  if(cmtarget.GetType() != cmTarget::EXECUTABLE &&
     cmtarget.GetType() != cmTarget::SHARED_LIBRARY &&
     cmtarget.GetType() != cmTarget::MODULE_LIBRARY)
    {
    return;
    }

  const char* llang = cmtarget.GetLinkerLanguage("NOCONFIG");
  if(!llang) { return; }

  // If the language is compiled as a source trust Xcode to link with it.
  cmTarget::LinkImplementation const* impl =
    cmtarget.GetLinkImplementation("NOCONFIG");
  for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
      li != impl->Languages.end(); ++li)
    {
    if(*li == llang) { return; }
    }

  // Add an empty source file to the target that compiles with the
  // linker language.  This should convince Xcode to choose the proper
  // language.
  cmMakefile* mf = cmtarget.GetMakefile();
  std::string fname = mf->GetCurrentOutputDirectory();
  fname += cmake::GetCMakeFilesDirectory();
  fname += "/";
  fname += cmtarget.GetName();
  fname += "-CMakeForceLinker";
  fname += ".";
  fname += cmSystemTools::LowerCase(llang);
  {
  cmGeneratedFileStream fout(fname.c_str());
  fout << "\n";
  }
  if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
    {
    sf->SetProperty("LANGUAGE", llang);
    cmtarget.AddSourceFile(sf);
    }
}

//----------------------------------------------------------------------------
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
  const std::vector<std::string>& hdrExts =
    this->CurrentMakefile->GetHeaderExtensions();
  return (std::find(hdrExts.begin(), hdrExts.end(), sf->GetExtension()) !=
          hdrExts.end());
}

//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateBuildPhase(const char* name,
                                         const char* name2,
                                         cmTarget& cmtarget,
                                         const std::vector<cmCustomCommand>&
                                         commands)
{
  if(commands.size() == 0 && strcmp(name, "CMake ReRun") != 0)
    {
    return 0;
    }
  cmXCodeObject* buildPhase = 
    this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
  buildPhase->AddAttribute("buildActionMask",
                           this->CreateString("2147483647"));
  cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  buildPhase->AddAttribute("files", buildFiles);
  buildPhase->AddAttribute("name", 
                           this->CreateString(name));
  buildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
                           this->CreateString("0"));
  buildPhase->AddAttribute("shellPath",
                           this->CreateString("/bin/sh"));
  this->AddCommandsToBuildPhase(buildPhase, cmtarget, commands,
                                name2);
  return buildPhase;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
                                                  cmXCodeObject*
                                                  sourceBuildPhase,
                                                  cmXCodeObject*
                                                  headerBuildPhase,
                                                  cmXCodeObject*
                                                  resourceBuildPhase,
                                                  std::vector<cmXCodeObject*>
                                                  contentBuildPhases,
                                                  cmXCodeObject*
                                                  frameworkBuildPhase,
                                                  cmTarget& cmtarget)
{
  std::vector<cmCustomCommand> const & prebuild 
    = cmtarget.GetPreBuildCommands();
  std::vector<cmCustomCommand> const & prelink 
    = cmtarget.GetPreLinkCommands();
  std::vector<cmCustomCommand> const & postbuild 
    = cmtarget.GetPostBuildCommands();
  std::vector<cmSourceFile*>const &classes = cmtarget.GetSourceFiles();
  // add all the sources
  std::vector<cmCustomCommand> commands;
  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); 
      i != classes.end(); ++i)
    {
    if((*i)->GetCustomCommand())
      {
      commands.push_back(*(*i)->GetCustomCommand());
      }
    }
  std::vector<cmCustomCommand> reruncom;
  cmXCodeObject* cmakeReRunPhase =  
    this->CreateBuildPhase("CMake ReRun", "cmakeReRunPhase",
                           cmtarget, reruncom);
  buildPhases->AddObject(cmakeReRunPhase);
  // create prebuild phase
  cmXCodeObject* cmakeRulesBuildPhase =
    this->CreateBuildPhase("CMake Rules",
                           "cmakeRulesBuildPhase",
                           cmtarget, commands);
  // create prebuild phase
  cmXCodeObject* preBuildPhase = 
    this->CreateBuildPhase("CMake PreBuild Rules", "preBuildCommands",
                           cmtarget, prebuild);
  // create prelink phase
  cmXCodeObject* preLinkPhase = 
    this->CreateBuildPhase("CMake PreLink Rules", "preLinkCommands",
                           cmtarget, prelink);
  // create postbuild phase
  cmXCodeObject* postBuildPhase = 
    this->CreateBuildPhase("CMake PostBuild Rules", "postBuildPhase",
                           cmtarget, postbuild);

  // The order here is the order they will be built in.
  // The order "headers, resources, sources" mimics a native project generated
  // from an xcode template...
  //
  if(preBuildPhase)
    {
    buildPhases->AddObject(preBuildPhase);
    }
  if(cmakeRulesBuildPhase)
    {
    buildPhases->AddObject(cmakeRulesBuildPhase);
    }
  if(headerBuildPhase)
    {
    buildPhases->AddObject(headerBuildPhase);
    }
  if(resourceBuildPhase)
    {
    buildPhases->AddObject(resourceBuildPhase);
    }
  std::vector<cmXCodeObject*>::iterator cit;
  for (cit = contentBuildPhases.begin(); cit != contentBuildPhases.end();
       ++cit)
    {
    buildPhases->AddObject(*cit);
    }
  if(sourceBuildPhase)
    {
    buildPhases->AddObject(sourceBuildPhase);
    }
  if(preLinkPhase)
    {
    buildPhases->AddObject(preLinkPhase);
    }
  if(frameworkBuildPhase)
    {
    buildPhases->AddObject(frameworkBuildPhase);
    }
  if(postBuildPhase)
    {
    buildPhases->AddObject(postBuildPhase);
    }
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
                                                std::string& flags)
{
  std::string retFlag;
  std::string::size_type pos = flags.find(flag);
  if(pos != flags.npos && (pos ==0 || flags[pos-1]==' '))
    {
    while(pos < flags.size() && flags[pos] != ' ')
      {
      retFlag += flags[pos];
      flags[pos] = ' ';
      pos++;
      }
    }
  return retFlag;
}

//----------------------------------------------------------------------------
void 
cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
                                                cmTarget& target,
                                                std::vector<cmCustomCommand> 
                                                const & commands,
                                                const char* name)
{
  if(strcmp(name, "cmakeReRunPhase") == 0)
    {
    std::string cdir = this->CurrentMakefile->GetHomeOutputDirectory();
    cdir = this->ConvertToRelativeForMake(cdir.c_str());
    std::string makecmd = "make -C ";
    makecmd += cdir;
    makecmd += " -f ";
    makecmd += 
      this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile.c_str());
    cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
    buildphase->AddAttribute("shellScript",
                             this->CreateString(makecmd.c_str()));
    return;
    }

  // collect multiple outputs of custom commands into a set
  // which will be used for every configuration
  std::map<cmStdString, cmStdString> multipleOutputPairs;
  for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
      i != commands.end(); ++i)
    {
    cmCustomCommand const& cc = *i; 
    if(!cc.GetCommandLines().empty())
      {
      const std::vector<std::string>& outputs = cc.GetOutputs();
      if(!outputs.empty())
        {
        // If there are more than one outputs treat the
        // first as the primary output and make the rest depend on it.
        std::vector<std::string>::const_iterator o = outputs.begin();
        std::string primaryOutput = this->ConvertToRelativeForMake(o->c_str());
        for(++o; o != outputs.end(); ++o)
          {
          std::string currentOutput=this->ConvertToRelativeForMake(o->c_str());
          multipleOutputPairs[currentOutput] = primaryOutput;
          }
        }
      }
    }
    
  std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
  dir += "/CMakeScripts";
  cmSystemTools::MakeDirectory(dir.c_str());
  std::string makefile = dir;
  makefile += "/";
  makefile += target.GetName();
  makefile += "_";
  makefile += name;
  makefile += ".make";
  
  for (std::vector<std::string>::const_iterator currentConfig= 
            this->CurrentConfigurationTypes.begin();
       currentConfig!=this->CurrentConfigurationTypes.end();
       currentConfig++ )
    {
    this->CreateCustomRulesMakefile(makefile.c_str(), 
                                    target, 
                                    commands, 
                                    currentConfig->c_str(),
                                    multipleOutputPairs);
    }
  
  std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory();
  cdir = this->ConvertToRelativeForXCode(cdir.c_str());
  std::string makecmd = "make -C ";
  makecmd += cdir;
  makecmd += " -f ";
  makecmd += this->ConvertToRelativeForMake(
                                          (makefile+"$CONFIGURATION").c_str());
  if(!multipleOutputPairs.empty())
    {
    makecmd += " cmake_check_multiple_outputs";
    }
  makecmd += " all";
  cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
  buildphase->AddAttribute("shellScript", 
                           this->CreateString(makecmd.c_str()));
}

//----------------------------------------------------------------------------
void  cmGlobalXCodeGenerator
::CreateCustomRulesMakefile(const char* makefileBasename, 
                            cmTarget& target, 
                            std::vector<cmCustomCommand> 
                            const & commands,
                            const char* configName,
                            const std::map<cmStdString, 
                            cmStdString>& multipleOutputPairs
                           )
{
  std::string makefileName=makefileBasename;
  if(this->XcodeVersion > 20)
    {
    makefileName+=configName;
    }
  cmGeneratedFileStream makefileStream(makefileName.c_str());
  if(!makefileStream)
    {
    return;
    }
  makefileStream.SetCopyIfDifferent(true);
  makefileStream << "# Generated by CMake, DO NOT EDIT\n";
  makefileStream << "# Custom rules for " << target.GetName() << "\n";
  
  // have all depend on all outputs
  makefileStream << "all: ";
  std::map<const cmCustomCommand*, cmStdString> tname;
  int count = 0;
  for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
      i != commands.end(); ++i)
    {
    cmCustomCommand const& cc = *i; 
    if(!cc.GetCommandLines().empty())
      {
      const std::vector<std::string>& outputs = cc.GetOutputs();
      if(!outputs.empty())
        {
        for(std::vector<std::string>::const_iterator o = outputs.begin();
            o != outputs.end(); ++o)
          {
          makefileStream
              << "\\\n\t" << this->ConvertToRelativeForMake(o->c_str());
          }
        }
      else
        {  
        cmOStringStream str;
        str << "_buildpart_" << count++ ;
        tname[&cc] = std::string(target.GetName()) + str.str(); 
        makefileStream << "\\\n\t" << tname[&cc];
        }
      }
    }
  makefileStream << "\n\n";
  for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
      i != commands.end(); ++i)
    {
    cmCustomCommand const& cc = *i; 
    if(!cc.GetCommandLines().empty())
      {
      bool escapeOldStyle = cc.GetEscapeOldStyle();
      bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars();
      makefileStream << "\n";
      const std::vector<std::string>& outputs = cc.GetOutputs();
      if(!outputs.empty())
        {
        // There is at least one output, start the rule for it
        std::string primary_output =
            this->ConvertToRelativeForMake(outputs.begin()->c_str());
        makefileStream << primary_output << ": ";
        }
      else
        {
        // There are no outputs.  Use the generated force rule name.
        makefileStream << tname[&cc] << ": ";
        }
      for(std::vector<std::string>::const_iterator d = 
          cc.GetDepends().begin();
          d != cc.GetDepends().end(); ++d)
        {
        std::string dep =
          this->CurrentLocalGenerator->GetRealDependency(d->c_str(),
                                                         configName);
        makefileStream << "\\\n" << this
          ->ConvertToRelativeForMake(dep.c_str());
        }
      makefileStream << "\n";

      if(const char* comment = cc.GetComment())
        {
        std::string echo_cmd = "echo ";
        echo_cmd += (this->CurrentLocalGenerator->
                     EscapeForShell(comment, escapeAllowMakeVars));
        makefileStream << "\t" << echo_cmd.c_str() << "\n";
        }

      // Add each command line to the set of commands.
      for(cmCustomCommandLines::const_iterator cl = 
          cc.GetCommandLines().begin();
          cl != cc.GetCommandLines().end(); ++cl)
        {
        // Build the command line in a single string.
        const cmCustomCommandLine& commandLine = *cl;
        std::string cmd2 = this->CurrentLocalGenerator
                         ->GetRealLocation(commandLine[0].c_str(), configName);
        
        cmSystemTools::ReplaceString(cmd2, "/./", "/");
        cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
        std::string cmd;
        if(cc.GetWorkingDirectory())
          {
          cmd += "cd ";
          cmd += this->ConvertToRelativeForMake(cc.GetWorkingDirectory());
          cmd += " && ";
          }
        cmd += cmd2;
        for(unsigned int j=1; j < commandLine.size(); ++j)
          {
          cmd += " ";
          if(escapeOldStyle)
            {
            cmd += (this->CurrentLocalGenerator
                ->EscapeForShellOldStyle(commandLine[j].c_str()));
            }
          else
            {
            cmd += (this->CurrentLocalGenerator->
                EscapeForShell(commandLine[j].c_str(),
                               escapeAllowMakeVars));
            }
          }
        makefileStream << "\t" << cmd.c_str() << "\n";
        }
      }
    }

  // Add rules to deal with multiple outputs of custom commands.
  if(!multipleOutputPairs.empty())
    {
    makefileStream << 
        "\n# Dependencies of multiple outputs to their primary outputs \n";

    for(std::map<cmStdString, cmStdString>::const_iterator o =
        multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
      {
      makefileStream << o->first << ": " << o->second << "\n";
      }

    makefileStream <<
        "\n"
        "cmake_check_multiple_outputs:\n";
    for(std::map<cmStdString, cmStdString>::const_iterator o =
        multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
      {
      makefileStream << "\t@if [ ! -f "
          << o->first << " ]; then rm -f "
          << o->second << "; fi\n";
      }
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
                                                 cmXCodeObject* buildSettings,
                                                 const char* configName)
{
  std::string flags;
  std::string defFlags;
  bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
                 (target.GetType() == cmTarget::MODULE_LIBRARY));

  const char* lang = target.GetLinkerLanguage(configName);
  std::string cflags;
  if(lang)
    {
    // for c++ projects get the c flags as well
    if(strcmp(lang, "CXX") == 0)
      {
      this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
      this->CurrentLocalGenerator->AddSharedFlags(cflags, lang, shared);
      }

    // Add language-specific flags.
    this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
    
    // Add shared-library flags if needed.
    this->CurrentLocalGenerator->AddSharedFlags(flags, lang, shared);
    }

  // Add define flags
  this->CurrentLocalGenerator->
    AppendFlags(defFlags,
                this->CurrentMakefile->GetDefineFlags());

  // Add preprocessor definitions for this target and configuration.
  BuildObjectListOrString ppDefs(this, this->XcodeVersion >= 30);
  if(this->XcodeVersion > 15)
    {
    this->AppendDefines(ppDefs, "CMAKE_INTDIR=\"$(CONFIGURATION)\"");
    }
  if(const char* exportMacro = target.GetExportMacro())
    {
    // Add the export symbol definition for shared library objects.
    this->AppendDefines(ppDefs, exportMacro);
    }
  this->AppendDefines
    (ppDefs, this->CurrentMakefile->GetProperty("COMPILE_DEFINITIONS"));
  this->AppendDefines(ppDefs, target.GetProperty("COMPILE_DEFINITIONS"));
  if(configName)
    {
    std::string defVarName = "COMPILE_DEFINITIONS_";
    defVarName += cmSystemTools::UpperCase(configName);
    this->AppendDefines
      (ppDefs, this->CurrentMakefile->GetProperty(defVarName.c_str()));
    this->AppendDefines(ppDefs, target.GetProperty(defVarName.c_str()));
    }
  buildSettings->AddAttribute
    ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());

  std::string extraLinkOptions;
  if(target.GetType() == cmTarget::EXECUTABLE)
    {
    extraLinkOptions = 
      this->CurrentMakefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS");
    std::string var = "CMAKE_EXE_LINKER_FLAGS_";
    var += cmSystemTools::UpperCase(configName);
    std::string val =  
      this->CurrentMakefile->GetSafeDefinition(var.c_str());
    if(val.size())
      {
      extraLinkOptions += " ";
      extraLinkOptions += val;
      }
    }
  if(target.GetType() == cmTarget::SHARED_LIBRARY)
    {
    extraLinkOptions = this->CurrentMakefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS");
    }
  if(target.GetType() == cmTarget::MODULE_LIBRARY)
    {
    extraLinkOptions = this->CurrentMakefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS");
    }
  
  const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
  if(targetLinkFlags)
    {
    extraLinkOptions += " ";
    extraLinkOptions += targetLinkFlags;
    }
  if(configName && *configName)
    {
    std::string linkFlagsVar = "LINK_FLAGS_";
    linkFlagsVar += cmSystemTools::UpperCase(configName);
    if(const char* linkFlags = target.GetProperty(linkFlagsVar.c_str()))
      {
      extraLinkOptions += " ";
      extraLinkOptions += linkFlags;
      }
    }

  // Set target-specific architectures.
  std::vector<std::string> archs;
  target.GetAppleArchs(configName, archs);
  if(!archs.empty())
    {
    // Enable ARCHS attribute.
    buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
                                this->CreateString("NO"));

    // Store ARCHS value.
    if(archs.size() == 1)
      {
      buildSettings->AddAttribute("ARCHS",
                                  this->CreateString(archs[0].c_str()));
      }
    else
      {
      cmXCodeObject* archObjects =
        this->CreateObject(cmXCodeObject::OBJECT_LIST);
      for(std::vector<std::string>::iterator i = archs.begin();
          i != archs.end(); i++)
        {
        archObjects->AddObject(this->CreateString((*i).c_str()));
        }
      buildSettings->AddAttribute("ARCHS", archObjects);
      }
    }

  // Get the product name components.
  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()));

  // Set attributes to specify the proper name for the target.
  std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory();
  if(target.GetType() == cmTarget::STATIC_LIBRARY ||
     target.GetType() == cmTarget::SHARED_LIBRARY ||
     target.GetType() == cmTarget::MODULE_LIBRARY ||
     target.GetType() == cmTarget::EXECUTABLE)
    {
    if(this->XcodeVersion >= 21)
      {
      std::string pncdir = target.GetDirectory(configName);
      buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
                                  this->CreateString(pncdir.c_str()));
      }
    else
      {
      buildSettings->AddAttribute("OBJROOT",
                                  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()));
    }
  buildSettings->AddAttribute("SYMROOT",
                              this->CreateString(pndir.c_str()));

  // Handle settings for each target type.
  switch(target.GetType())
    {
    case cmTarget::STATIC_LIBRARY:
    {
    buildSettings->AddAttribute("LIBRARY_STYLE", 
                                this->CreateString("STATIC"));
    break;
    }
    
    case cmTarget::MODULE_LIBRARY:
    {
    buildSettings->AddAttribute("LIBRARY_STYLE", 
                                this->CreateString("BUNDLE"));
    if(this->XcodeVersion >= 22)
      {
      buildSettings->AddAttribute("MACH_O_TYPE", 
                                  this->CreateString("mh_bundle"));
      buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC", 
                                  this->CreateString("NO"));
      // Add the flags to create an executable.
      std::string createFlags =
        this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
      if(!createFlags.empty())
        {
        extraLinkOptions += " ";
        extraLinkOptions += createFlags;
        }
      }
    else
      {
      // Add the flags to create a module.
      std::string createFlags =
        this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
                          "-bundle");
      if(!createFlags.empty())
        {
        extraLinkOptions += " ";
        extraLinkOptions += createFlags;
        }
      }
    break;
    }
    case cmTarget::SHARED_LIBRARY:
    {
    if(target.GetPropertyAsBool("FRAMEWORK"))
      {
      std::string version = target.GetFrameworkVersion();
      buildSettings->AddAttribute("FRAMEWORK_VERSION",
                                  this->CreateString(version.c_str()));

      std::string plist = this->ComputeInfoPListLocation(target);
      // Xcode will create the final version of Info.plist at build time,
      // so let it replace the framework name.  This avoids creating
      // a per-configuration Info.plist file.
      this->CurrentLocalGenerator
        ->GenerateFrameworkInfoPList(&target, "$(EXECUTABLE_NAME)",
                                     plist.c_str());
      std::string path =
        this->ConvertToRelativeForXCode(plist.c_str());
      buildSettings->AddAttribute("INFOPLIST_FILE",
                                  this->CreateString(path.c_str()));
      }
    else
      {
      // Add the flags to create a shared library.
      std::string createFlags =
        this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS",
                          "-dynamiclib");
      if(!createFlags.empty())
        {
        extraLinkOptions += " ";
        extraLinkOptions += createFlags;
        }
      }

    buildSettings->AddAttribute("LIBRARY_STYLE",
                                this->CreateString("DYNAMIC"));
    break;
    }
    case cmTarget::EXECUTABLE:
    {
    // Add the flags to create an executable.
    std::string createFlags =
      this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
    if(!createFlags.empty())
      {
      extraLinkOptions += " ";
      extraLinkOptions += createFlags;
      }

    // Handle bundles and normal executables separately.
    if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
      {
      std::string plist = this->ComputeInfoPListLocation(target);
      // Xcode will create the final version of Info.plist at build time,
      // so let it replace the executable name.  This avoids creating
      // a per-configuration Info.plist file.
      this->CurrentLocalGenerator
        ->GenerateAppleInfoPList(&target, "$(EXECUTABLE_NAME)",
                                 plist.c_str());
      std::string path =
        this->ConvertToRelativeForXCode(plist.c_str());
      buildSettings->AddAttribute("INFOPLIST_FILE", 
                                  this->CreateString(path.c_str()));

      }
    }
    break;
    default:
      break;
    }
  if(this->XcodeVersion >= 22)
    {
    buildSettings->AddAttribute("PREBINDING", 
                                this->CreateString("NO"));
    }

  BuildObjectListOrString dirs(this, this->XcodeVersion >= 30);
  BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30);
  std::vector<std::string> includes;
  this->CurrentLocalGenerator->GetIncludeDirectories(includes);
  std::set<cmStdString> emitted;
  emitted.insert("/System/Library/Frameworks");
  for(std::vector<std::string>::iterator i = includes.begin();
      i != includes.end(); ++i)
    {
    if(this->NameResolvesToFramework(i->c_str()))
      {
      std::string frameworkDir = *i;
      frameworkDir += "/../";
      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
      if(emitted.insert(frameworkDir).second)
        {
        fdirs.Add(this->XCodeEscapePath(frameworkDir.c_str()).c_str());
        }
      }
    else
      {
      std::string incpath = 
        this->XCodeEscapePath(i->c_str());
      dirs.Add(incpath.c_str());
      }
    }
  std::vector<std::string>& frameworks = target.GetFrameworks();
  if(frameworks.size())
    {
    for(std::vector<std::string>::iterator fmIt = frameworks.begin();
        fmIt != frameworks.end(); ++fmIt)
      {
      if(emitted.insert(*fmIt).second)
        {
        fdirs.Add(this->XCodeEscapePath(fmIt->c_str()).c_str());
        }
      }
    }
  if(!fdirs.IsEmpty())
    {
    buildSettings->AddAttribute("FRAMEWORK_SEARCH_PATHS", 
                                fdirs.CreateList());
    }
  if(!dirs.IsEmpty())
    {
    buildSettings->AddAttribute("HEADER_SEARCH_PATHS", 
                                dirs.CreateList());
    }
  std::string oflagc = this->ExtractFlag("-O", cflags);
  char optLevel[2];
  optLevel[0] = '0';
  optLevel[1] = 0;
  if(oflagc.size() == 3)
    {
    optLevel[0] = oflagc[2];
    }
  if(oflagc.size() == 2)
    {
    optLevel[0] = '1';
    }
  std::string oflag = this->ExtractFlag("-O", flags);
  if(oflag.size() == 3)
    {
    optLevel[0] = oflag[2];
    }
  if(oflag.size() == 2)
    {
    optLevel[0] = '1';
    }
  std::string gflagc = this->ExtractFlag("-g", cflags);
  // put back gdwarf-2 if used since there is no way
  // to represent it in the gui, but we still want debug yes
  if(gflagc == "-gdwarf-2")
    {
    cflags += " ";
    cflags += gflagc;
    }
  std::string gflag = this->ExtractFlag("-g", flags);
  if(gflag == "-gdwarf-2")
    {
    flags += " ";
    flags += gflag;
    }
  const char* debugStr = "YES";
  if(gflagc.size() ==0  && gflag.size() == 0)
    {
    debugStr = "NO";
    }    

  buildSettings->AddAttribute("GCC_GENERATE_DEBUGGING_SYMBOLS",
                              this->CreateString(debugStr));
  buildSettings->AddAttribute("GCC_OPTIMIZATION_LEVEL", 
                              this->CreateString(optLevel));
  buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN",
                              this->CreateString("NO"));
  buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN",
                              this->CreateString("NO"));
  if(lang && strcmp(lang, "CXX") == 0)
    {
    flags += " ";
    flags += defFlags;
    buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS", 
                                this->CreateString(flags.c_str()));
    cflags += " ";
    cflags += defFlags;
    buildSettings->AddAttribute("OTHER_CFLAGS", 
                                this->CreateString(cflags.c_str()));

    }
  else
    {
    flags += " ";
    flags += defFlags;
    buildSettings->AddAttribute("OTHER_CFLAGS", 
                                this->CreateString(flags.c_str()));
    }

  // Create the INSTALL_PATH attribute.
  std::string install_name_dir;
  if(target.GetType() == cmTarget::SHARED_LIBRARY)
    {
    // Get the install_name directory for the build tree.
    install_name_dir = target.GetInstallNameDirForBuildTree(configName, true);
    if(install_name_dir.empty())
      {
      // Xcode will not pass the -install_name option at all if INSTALL_PATH
      // is not given or is empty.  We must explicitly put the flag in the
      // link flags to create an install_name with just the library soname.
      extraLinkOptions += " -install_name ";
      extraLinkOptions += target.GetFullName(configName);
      }
    else
      {
      // Convert to a path for the native build tool.
      cmSystemTools::ConvertToUnixSlashes(install_name_dir);
      // do not escape spaces on this since it is only a single path
      }
    }
  buildSettings->AddAttribute("INSTALL_PATH",
                              this->CreateString(install_name_dir.c_str()));

  buildSettings->AddAttribute("OTHER_LDFLAGS", 
                              this->CreateString(extraLinkOptions.c_str()));
  buildSettings->AddAttribute("OTHER_REZFLAGS", 
                              this->CreateString(""));
  buildSettings->AddAttribute("SECTORDER_FLAGS",
                              this->CreateString(""));
  buildSettings->AddAttribute("USE_HEADERMAP",
                              this->CreateString("NO"));
  if (this->XcodeVersion >= 30)
    {
    cmXCodeObject *group = this->CreateObject(cmXCodeObject::OBJECT_LIST);
    group->AddObject(this->CreateString("-Wmost"));
    group->AddObject(this->CreateString("-Wno-four-char-constants"));
    group->AddObject(this->CreateString("-Wno-unknown-pragmas"));
    buildSettings->AddAttribute("WARNING_CFLAGS", group);
    }
  else
    {
    buildSettings->AddAttribute("WARNING_CFLAGS",
                                this->CreateString(
                                  "-Wmost -Wno-four-char-constants"
                                  " -Wno-unknown-pragmas"));
    }

  // Runtime version information.
  if(target.GetType() == cmTarget::SHARED_LIBRARY)
    {
    int major;
    int minor;
    int patch;

    // VERSION -> current_version
    target.GetTargetVersion(false, major, minor, patch);
    cmOStringStream v;

    // Xcode always wants at least 1.0.0 or nothing
    if(!(major == 0 && minor == 0 && patch == 0))
      {
      v << major << "." << minor << "." << patch;
      }
    buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
                                this->CreateString(v.str().c_str()));

    // SOVERSION -> compatibility_version
    target.GetTargetVersion(true, major, minor, patch);
    cmOStringStream vso;

    // Xcode always wants at least 1.0.0 or nothing
    if(!(major == 0 && minor == 0 && patch == 0))
      {
      vso << major << "." << minor << "." << patch;
      }
    buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
                                this->CreateString(vso.str().c_str()));
    }
  // put this last so it can override existing settings
  // Convert "XCODE_ATTRIBUTE_*" properties directly.
  {
  cmPropertyMap const& props = target.GetProperties();
  for(cmPropertyMap::const_iterator i = props.begin();
      i != props.end(); ++i)
    {
    if(i->first.find("XCODE_ATTRIBUTE_") == 0)
      {
      buildSettings->AddAttribute(i->first.substr(16).c_str(),
                                  this->CreateString(i->second.GetValue()));
      }
    }
  }
}

//----------------------------------------------------------------------------
cmXCodeObject* 
cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
{
  cmXCodeObject* shellBuildPhase =
    this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
  shellBuildPhase->AddAttribute("buildActionMask", 
                                this->CreateString("2147483647"));
  cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  shellBuildPhase->AddAttribute("files", buildFiles);
  cmXCodeObject* inputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  shellBuildPhase->AddAttribute("inputPaths", inputPaths);
  cmXCodeObject* outputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  shellBuildPhase->AddAttribute("outputPaths", outputPaths);
  shellBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
                                this->CreateString("0"));
  shellBuildPhase->AddAttribute("shellPath",
                                this->CreateString("/bin/sh"));
  shellBuildPhase->AddAttribute("shellScript",
                                this->CreateString(
                                  "# shell script goes here\nexit 0"));
  cmXCodeObject* target = 
    this->CreateObject(cmXCodeObject::PBXAggregateTarget);
  target->SetComment(cmtarget.GetName());
  cmXCodeObject* buildPhases = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  std::vector<cmXCodeObject*> emptyContentVector;
  this->CreateCustomCommands(buildPhases, 0, 0, 0, emptyContentVector, 0,
                             cmtarget);
  target->AddAttribute("buildPhases", buildPhases);
  if(this->XcodeVersion > 20)
    {
    this->AddConfigurations(target, cmtarget);
    }
  else
    {
    const char* theConfig =
      this->CurrentMakefile->GetDefinition("CMAKE_BUILD_TYPE");
    cmXCodeObject* buildSettings =
      this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
    this->CreateBuildSettings(cmtarget, buildSettings, theConfig);
    target->AddAttribute("buildSettings", buildSettings);
    }
  cmXCodeObject* dependencies = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  target->AddAttribute("dependencies", dependencies);
  target->AddAttribute("name", this->CreateString(cmtarget.GetName()));
  target->AddAttribute("productName",this->CreateString(cmtarget.GetName()));
  target->SetTarget(&cmtarget);

  // Add source files without build rules for editing convenience.
  if(cmtarget.GetType() == cmTarget::UTILITY)
    {
    std::vector<cmSourceFile*> const& sources = cmtarget.GetSourceFiles();
    for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
        i != sources.end(); ++i)
      {
      if(!(*i)->GetPropertyAsBool("GENERATED"))
        {
        this->CreateXCodeFileReference(*i, cmtarget);
        }
      }
    }

  return target;
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
                                                      cmTarget& cmtarget)
{
  std::string configTypes = 
    this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES");
  std::vector<std::string> configVectorIn;
  std::vector<std::string> configVector;
  configVectorIn.push_back(configTypes);
  cmSystemTools::ExpandList(configVectorIn, configVector);
  cmXCodeObject* configlist = 
    this->CreateObject(cmXCodeObject::XCConfigurationList);
  cmXCodeObject* buildConfigurations =
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  configlist->AddAttribute("buildConfigurations", buildConfigurations);
  std::string comment = "Build configuration list for ";
  comment += cmXCodeObject::PBXTypeNames[target->GetIsA()];
  comment += " \"";
  comment += cmtarget.GetName();
  comment += "\"";
  configlist->SetComment(comment.c_str());
  target->AddAttribute("buildConfigurationList", 
                       this->CreateObjectReference(configlist));
  for(unsigned int i = 0; i < configVector.size(); ++i)
    {
    cmXCodeObject* config = 
      this->CreateObject(cmXCodeObject::XCBuildConfiguration);
    buildConfigurations->AddObject(config);
    cmXCodeObject* buildSettings =
      this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
    this->CreateBuildSettings(cmtarget, buildSettings,
                              configVector[i].c_str());
    config->AddAttribute("name", this->CreateString(configVector[i].c_str()));
    config->SetComment(configVector[i].c_str());
    config->AddAttribute("buildSettings", buildSettings);
    }
  if(configVector.size())
    {
    configlist->AddAttribute("defaultConfigurationName", 
                             this->CreateString(configVector[0].c_str()));
    configlist->AddAttribute("defaultConfigurationIsVisible", 
                             this->CreateString("0"));
    return configVector[0];
    }
  return "";
}

//----------------------------------------------------------------------------
const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
{
  switch(cmtarget.GetType())
    {
    case cmTarget::STATIC_LIBRARY:
      return "archive.ar";
    case cmTarget::MODULE_LIBRARY:
      return ((this->XcodeVersion >= 22)?
              "compiled.mach-o.executable" : "compiled.mach-o.dylib");
    case cmTarget::SHARED_LIBRARY:
      return (cmtarget.GetPropertyAsBool("FRAMEWORK")?
              "wrapper.framework" : "compiled.mach-o.dylib");
    case cmTarget::EXECUTABLE:
      return "compiled.mach-o.executable";
    default: break;
    }
  return 0;
}

//----------------------------------------------------------------------------
const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
{
  switch(cmtarget.GetType())
    {
    case cmTarget::STATIC_LIBRARY:
      return "com.apple.product-type.library.static";
    case cmTarget::MODULE_LIBRARY:
      return ((this->XcodeVersion >= 22)? "com.apple.product-type.tool" :
              "com.apple.product-type.library.dynamic");
    case cmTarget::SHARED_LIBRARY:
      return (cmtarget.GetPropertyAsBool("FRAMEWORK")?
              "com.apple.product-type.framework" :
              "com.apple.product-type.library.dynamic");
    case cmTarget::EXECUTABLE:
      return (cmtarget.GetPropertyAsBool("MACOSX_BUNDLE")?
              "com.apple.product-type.application" :
              "com.apple.product-type.tool");
    default: break;
    }
  return 0;
}

//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
                                          cmXCodeObject* buildPhases)
{
  cmXCodeObject* target = 
    this->CreateObject(cmXCodeObject::PBXNativeTarget);
  target->AddAttribute("buildPhases", buildPhases);
  cmXCodeObject* buildRules = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  target->AddAttribute("buildRules", buildRules);
  std::string defConfig;
  if(this->XcodeVersion > 20)
    {
    defConfig = this->AddConfigurations(target, cmtarget);
    }
  else
    {
    cmXCodeObject* buildSettings =
      this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
    defConfig = this->CurrentMakefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
    this->CreateBuildSettings(cmtarget, buildSettings, defConfig.c_str());
    target->AddAttribute("buildSettings", buildSettings);
    }
  cmXCodeObject* dependencies = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  target->AddAttribute("dependencies", dependencies);
  target->AddAttribute("name", this->CreateString(cmtarget.GetName()));
  target->AddAttribute("productName",this->CreateString(cmtarget.GetName()));

  cmXCodeObject* fileRef = 
    this->CreateObject(cmXCodeObject::PBXFileReference);
  if(const char* fileType = this->GetTargetFileType(cmtarget))
    {
    fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
    }
  std::string fullName = cmtarget.GetFullName(defConfig.c_str());
  fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
  fileRef->AddAttribute("refType", this->CreateString("0"));
  fileRef->AddAttribute("sourceTree",
                        this->CreateString("BUILT_PRODUCTS_DIR"));
  fileRef->SetComment(cmtarget.GetName());
  target->AddAttribute("productReference", 
                       this->CreateObjectReference(fileRef));
  if(const char* productType = this->GetTargetProductType(cmtarget))
    {
    target->AddAttribute("productType", this->CreateString(productType));
    }
  target->SetTarget(&cmtarget);
  return target;
}

//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
{
  if(!t)
    {
    return 0;
    }
  for(std::vector<cmXCodeObject*>::iterator i = this->XCodeObjects.begin();
      i != this->XCodeObjects.end(); ++i)
    {
    cmXCodeObject* o = *i;
    if(o->GetTarget() == t)
      {
      return o;
      }
    }
  return 0;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
                                             cmXCodeObject* dependTarget)
{
  // make sure a target does not depend on itself
  if(target == dependTarget)
    {
    return;
    }
  // now avoid circular references if dependTarget already
  // depends on target then skip it.  Circular references crashes
  // xcode
  cmXCodeObject* dependTargetDepends = 
    dependTarget->GetObject("dependencies");
  if(dependTargetDepends)
    {
    if(dependTargetDepends->HasObject(target->GetPBXTargetDependency()))
      { 
      return;
      }
    }
  
  cmXCodeObject* targetdep = dependTarget->GetPBXTargetDependency();
  if(!targetdep)
    {
    cmXCodeObject* container = 
      this->CreateObject(cmXCodeObject::PBXContainerItemProxy);
    container->SetComment("PBXContainerItemProxy");
    container->AddAttribute("containerPortal",
                            this->CreateObjectReference(this->RootObject));
    container->AddAttribute("proxyType", this->CreateString("1"));
    container->AddAttribute("remoteGlobalIDString",
                            this->CreateObjectReference(dependTarget));
    container->AddAttribute("remoteInfo", 
                            this->CreateString(
                              dependTarget->GetTarget()->GetName()));
    targetdep = 
      this->CreateObject(cmXCodeObject::PBXTargetDependency);
    targetdep->SetComment("PBXTargetDependency");
    targetdep->AddAttribute("target",
                            this->CreateObjectReference(dependTarget));
    targetdep->AddAttribute("targetProxy", 
                            this->CreateObjectReference(container));
    dependTarget->SetPBXTargetDependency(targetdep);
    }
    
  cmXCodeObject* depends = target->GetObject("dependencies");
  if(!depends)
    {
    cmSystemTools::
      Error("target does not have dependencies attribute error..");
    
    }
  else
    {
    depends->AddUniqueObject(targetdep);
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
                                                     const char* attribute,
                                                     const char* value)
{
  if(settings)
    {
    cmXCodeObject* attr = settings->GetObject(attribute);
    if(!attr)
      {
      settings->AddAttribute(attribute, this->CreateString(value));
      }
    else
      {
      std::string oldValue = attr->GetString();
      oldValue += " ";
      oldValue += value;
      attr->SetString(oldValue.c_str());
      }
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator
::AppendBuildSettingAttribute(cmXCodeObject* target,
                              const char* attribute,
                              const char* value,
                              const char* configName)
{
  if(this->XcodeVersion < 21)
    {
    // There is only one configuration.  Add the setting to the buildSettings
    // of the target.
    this->AppendOrAddBuildSetting(target->GetObject("buildSettings"),
                                  attribute, value);
    }
  else
    {
    // There are multiple configurations.  Add the setting to the
    // buildSettings of the configuration name given.
    cmXCodeObject* configurationList = 
      target->GetObject("buildConfigurationList")->GetObject();
    cmXCodeObject* buildConfigs = 
      configurationList->GetObject("buildConfigurations");
    std::vector<cmXCodeObject*> list = buildConfigs->GetObjectList();
    // each configuration and the target itself has a buildSettings in it 
    //list.push_back(target);
    for(std::vector<cmXCodeObject*>::iterator i = list.begin(); 
        i != list.end(); ++i)
      {
      if(configName)
        {
        if(strcmp((*i)->GetObject("name")->GetString(), configName) == 0)
          {
          cmXCodeObject* settings = (*i)->GetObject("buildSettings");
          this->AppendOrAddBuildSetting(settings, attribute, value);
          }
        }
      else
        {
        cmXCodeObject* settings = (*i)->GetObject("buildSettings");
        this->AppendOrAddBuildSetting(settings, attribute, value);
        }
      }
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator
::AddDependAndLinkInformation(cmXCodeObject* target)
{
  cmTarget* cmtarget = target->GetTarget();
  if(!cmtarget)
    {
    cmSystemTools::Error("Error no target on xobject\n");
    return;
    }

  // Add dependencies on other CMake targets.
  TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget);
  for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i)
    {
    if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i))
      {
      this->AddDependTarget(target, dptarget);
      }
    }

  // Skip link information for static libraries.
  if(cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
    {
    return;
    }

  // Loop over configuration types and set per-configuration info.
  for(std::vector<std::string>::iterator i =
        this->CurrentConfigurationTypes.begin();
      i != this->CurrentConfigurationTypes.end(); ++i)
    {
    // Get the current configuration name.
    const char* configName = i->c_str();
    if(!*configName)
      {
      configName = 0;
      }

    // Compute the link library and directory information.
    cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
    if(!pcli)
      {
      continue;
      }
    cmComputeLinkInformation& cli = *pcli;

    // Add dependencies directly on library files.
    {
    std::vector<std::string> const& libDeps = cli.GetDepends();
    for(std::vector<std::string>::const_iterator j = libDeps.begin();
        j != libDeps.end(); ++j)
      {
      target->AddDependLibrary(configName, j->c_str());
      }
    }

    // add the library search paths
    {
    std::vector<std::string> const& libDirs = cli.GetDirectories();
    std::string linkDirs;
    for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
        libDir != libDirs.end(); ++libDir)
      {
      if(libDir->size() && *libDir != "/usr/lib")
        {
        if(this->XcodeVersion > 15)
          {
          // now add the same one but append $(CONFIGURATION) to it:
          linkDirs += " ";
          linkDirs += this->XCodeEscapePath(
            (*libDir + "/$(CONFIGURATION)").c_str());
          }
        linkDirs += " ";
        linkDirs += this->XCodeEscapePath(libDir->c_str());
        }
      }
    this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
                                      linkDirs.c_str(), configName);
    }

    // add the framework search paths
    {
    const char* sep = "";
    std::string fdirs;
    std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
    for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
        fdi != fwDirs.end(); ++fdi)
      {
      fdirs += sep;
      sep = " ";
      fdirs += this->XCodeEscapePath(fdi->c_str());
      }
    if(!fdirs.empty())
      {
      this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
                                        fdirs.c_str(), configName);
      }
    }

    // now add the link libraries
    {
    std::string linkLibs;
    const char* sep = "";
    typedef cmComputeLinkInformation::ItemVector ItemVector;
    ItemVector const& libNames = cli.GetItems();
    for(ItemVector::const_iterator li = libNames.begin();
        li != libNames.end(); ++li)
      {
      linkLibs += sep;
      sep = " ";
      if(li->IsPath)
        {
        linkLibs += this->XCodeEscapePath(li->Value.c_str());
        }
      else
        {
        linkLibs += li->Value;
        }
      }
    this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
                                      linkLibs.c_str(), configName);
    }
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
                                          std::vector<cmLocalGenerator*>&
                                          generators)
{
  for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
      i != generators.end(); ++i)
    {
    if(this->IsExcluded(root, *i))
      {
      continue;
      }
    cmMakefile* mf = (*i)->GetMakefile();
    std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
    cmTargets &tgts = mf->GetTargets();
    for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
      { 
      cmTarget& cmtarget = l->second;

      // Same skipping logic here as in CreateXCodeTargets so that we do not
      // end up with (empty anyhow) ALL_BUILD and XCODE_DEPEND_HELPER source
      // groups:
      //
      if(cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
        {
        continue;
        }

      // add the soon to be generated Info.plist file as a source for a
      // MACOSX_BUNDLE file
      if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
        {
        std::string plist = this->ComputeInfoPListLocation(cmtarget);
        cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
        cmtarget.AddSourceFile(sf);
        }

      std::vector<cmSourceFile*>  classes = cmtarget.GetSourceFiles();

      for(std::vector<cmSourceFile*>::const_iterator s = classes.begin(); 
          s != classes.end(); s++)
        {
        cmSourceFile* sf = *s;
        // Add the file to the list of sources.
        std::string const& source = sf->GetFullPath();
        cmSourceGroup& sourceGroup = 
          mf->FindSourceGroup(source.c_str(), sourceGroups);
        cmXCodeObject* pbxgroup = 
          this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
        cmStdString key = GetGroupMapKey(cmtarget, sf);
        this->GroupMap[key] = pbxgroup;
        }
      }
    } 
}

//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator
::CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg)
{
  cmStdString s = cmtarget.GetName();
  s += "/";
  s += sg->GetName();
  std::map<cmStdString, cmXCodeObject* >::iterator i =
    this->GroupNameMap.find(s);
  if(i != this->GroupNameMap.end())
    {
    return i->second;
    }
  i = this->TargetGroup.find(cmtarget.GetName());
  cmXCodeObject* tgroup = 0;
  if(i != this->TargetGroup.end())
    {
    tgroup = i->second;
    }
  else
    {
    tgroup = this->CreateObject(cmXCodeObject::PBXGroup);
    this->TargetGroup[cmtarget.GetName()] = tgroup;
    cmXCodeObject* tgroupChildren = 
      this->CreateObject(cmXCodeObject::OBJECT_LIST);
    tgroup->AddAttribute("name", this->CreateString(cmtarget.GetName()));
    tgroup->AddAttribute("children", tgroupChildren);
    if(this->XcodeVersion == 15)
      {
      tgroup->AddAttribute("refType", this->CreateString("4"));
      }
    tgroup->AddAttribute("sourceTree", this->CreateString("<group>"));
    this->SourcesGroupChildren->AddObject(tgroup);
    }

  // If it's the default source group (empty name) then put the source file
  // directly in the tgroup...
  //
  if (cmStdString(sg->GetName()) == "")
    {
    this->GroupNameMap[s] = tgroup;
    return tgroup;
    }

  cmXCodeObject* tgroupChildren = tgroup->GetObject("children");
  cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
  cmXCodeObject* groupChildren = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  group->AddAttribute("name", this->CreateString(sg->GetName()));
  group->AddAttribute("children", groupChildren);
  if(this->XcodeVersion == 15)
    {
    group->AddAttribute("refType", this->CreateString("4"));
    }
  group->AddAttribute("sourceTree", this->CreateString("<group>"));
  tgroupChildren->AddObject(group);
  this->GroupNameMap[s] = group;
  return group;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator
::CreateXCodeObjects(cmLocalGenerator* root,
                     std::vector<cmLocalGenerator*>&
                     generators)
{
  this->ClearXCodeObjects(); 
  this->RootObject = 0;
  this->SourcesGroupChildren = 0;
  this->ResourcesGroupChildren = 0;
  this->MainGroupChildren = 0;
  cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
  group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
  cmXCodeObject* developBuildStyle = 
    this->CreateObject(cmXCodeObject::PBXBuildStyle);
  cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  if(this->XcodeVersion == 15)
    {
    developBuildStyle->AddAttribute("name", 
                                    this->CreateString("Development"));
    developBuildStyle->AddAttribute("buildSettings", group);
    listObjs->AddObject(developBuildStyle);
    group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
    group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("YES"));
    cmXCodeObject* deployBuildStyle =
    this->CreateObject(cmXCodeObject::PBXBuildStyle);
    deployBuildStyle->AddAttribute("name", this->CreateString("Deployment"));
    deployBuildStyle->AddAttribute("buildSettings", group);
    listObjs->AddObject(deployBuildStyle);
    }
  else
    {
    for(unsigned int i = 0; i < this->CurrentConfigurationTypes.size(); ++i)
      {
      cmXCodeObject* buildStyle = 
        this->CreateObject(cmXCodeObject::PBXBuildStyle);
      const char* name = this->CurrentConfigurationTypes[i].c_str();
      buildStyle->AddAttribute("name", this->CreateString(name));
      buildStyle->SetComment(name);
      cmXCodeObject* sgroup =
        this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
      sgroup->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
      buildStyle->AddAttribute("buildSettings", sgroup);
      listObjs->AddObject(buildStyle);
      }
    }

  cmXCodeObject* mainGroup = this->CreateObject(cmXCodeObject::PBXGroup);
  this->MainGroupChildren = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  mainGroup->AddAttribute("children", this->MainGroupChildren);
  if(this->XcodeVersion == 15)
    {
    mainGroup->AddAttribute("refType", this->CreateString("4"));
    }
  mainGroup->AddAttribute("sourceTree", this->CreateString("<group>"));

  cmXCodeObject* sourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
  this->SourcesGroupChildren = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  sourcesGroup->AddAttribute("name", this->CreateString("Sources"));
  sourcesGroup->AddAttribute("children", this->SourcesGroupChildren);
  if(this->XcodeVersion == 15)
    {
    sourcesGroup->AddAttribute("refType", this->CreateString("4"));
    }
  sourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
  this->MainGroupChildren->AddObject(sourcesGroup);

  cmXCodeObject* resourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
  this->ResourcesGroupChildren =
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  resourcesGroup->AddAttribute("name", this->CreateString("Resources"));
  resourcesGroup->AddAttribute("children", this->ResourcesGroupChildren);
  if(this->XcodeVersion == 15)
    {
    resourcesGroup->AddAttribute("refType", this->CreateString("4"));
    }
  resourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
  this->MainGroupChildren->AddObject(resourcesGroup);

  // now create the cmake groups 
  this->CreateGroups(root, generators);

  cmXCodeObject* productGroup = this->CreateObject(cmXCodeObject::PBXGroup);
  productGroup->AddAttribute("name", this->CreateString("Products"));
  if(this->XcodeVersion == 15)
    {
    productGroup->AddAttribute("refType", this->CreateString("4"));
    }
  productGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
  cmXCodeObject* productGroupChildren = 
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  productGroup->AddAttribute("children", productGroupChildren);
  this->MainGroupChildren->AddObject(productGroup);
  
  
  this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
  this->RootObject->SetComment("Project object");
  group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
  this->RootObject->AddAttribute("mainGroup", 
                             this->CreateObjectReference(mainGroup));
  this->RootObject->AddAttribute("buildSettings", group);
  this->RootObject->AddAttribute("buildStyles", listObjs);
  this->RootObject->AddAttribute("hasScannedForEncodings",
                             this->CreateString("0"));
  if (this->XcodeVersion >= 30)
    {
    group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
    group->AddAttribute("BuildIndependentTargetsInParallel",
                        this->CreateString("YES"));
    this->RootObject->AddAttribute("attributes", group);
    if (this->XcodeVersion >= 31)
      this->RootObject->AddAttribute("compatibilityVersion",
                                     this->CreateString("Xcode 3.1"));
    else
      this->RootObject->AddAttribute("compatibilityVersion",
                                     this->CreateString("Xcode 3.0"));
    }
  // Point Xcode at the top of the source tree.
  {
  std::string pdir =
    this->RelativeToBinary(root->GetMakefile()->GetCurrentDirectory());
  this->RootObject->AddAttribute("projectDirPath",
                                 this->CreateString(pdir.c_str()));
  this->RootObject->AddAttribute("projectRoot", this->CreateString(""));
  }
  cmXCodeObject* configlist = 
    this->CreateObject(cmXCodeObject::XCConfigurationList);
  cmXCodeObject* buildConfigurations =
    this->CreateObject(cmXCodeObject::OBJECT_LIST);
  std::vector<cmXCodeObject*> configs;
  if(this->XcodeVersion == 15)
    {
    cmXCodeObject* configDebug = 
      this->CreateObject(cmXCodeObject::XCBuildConfiguration);
    configDebug->AddAttribute("name", this->CreateString("Debug"));
    configs.push_back(configDebug);
    cmXCodeObject* configRelease = 
      this->CreateObject(cmXCodeObject::XCBuildConfiguration);
    configRelease->AddAttribute("name", this->CreateString("Release"));
    configs.push_back(configRelease);
    }
  else
    {
    for(unsigned int i = 0; i < this->CurrentConfigurationTypes.size(); ++i)
      {
      const char* name = this->CurrentConfigurationTypes[i].c_str();
      cmXCodeObject* config = 
        this->CreateObject(cmXCodeObject::XCBuildConfiguration);
      config->AddAttribute("name", this->CreateString(name));
      configs.push_back(config);
      }
    }
  for(std::vector<cmXCodeObject*>::iterator c = configs.begin();
      c != configs.end(); ++c)
    {
    buildConfigurations->AddObject(*c);
    }
  configlist->AddAttribute("buildConfigurations", buildConfigurations);

  std::string comment = "Build configuration list for PBXProject ";
  comment += " \"";
  comment += this->CurrentProject;
  comment += "\"";
  configlist->SetComment(comment.c_str());
  configlist->AddAttribute("defaultConfigurationIsVisible", 
                           this->CreateString("0"));
  configlist->AddAttribute("defaultConfigurationName", 
                           this->CreateString("Debug"));
  cmXCodeObject* buildSettings =
      this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
  const char* osxArch = 
      this->CurrentMakefile->GetDefinition("CMAKE_OSX_ARCHITECTURES");
  if(strlen(osxArch) == 0)
    {
    if(this->XcodeVersion >= 32)
      {
      osxArch = "$(ARCHS_STANDARD_32_64_BIT)";
      }
    else if(this->XcodeVersion == 31)
      {
      osxArch = "$(ARCHS_STANDARD_32_BIT)";
      }
    else if(this->XcodeVersion <= 30)
      {
#ifdef __ppc__
      osxArch = "ppc";
#endif
#ifdef __i386
      osxArch = "i386";
#endif
      }
    buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
                                this->CreateString("YES"));
    }

  const char* sysroot = 
      this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT");
  const char* sysrootDefault = 
    this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT_DEFAULT");
  const char* deploymentTarget = 
    this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
  if(osxArch && sysroot)
    {
    bool flagsUsed = false;
    // recompute this as it may have been changed since enable language
    this->Architectures.clear();
    cmSystemTools::ExpandListArgument(std::string(osxArch),
                                      this->Architectures);
    flagsUsed = true;
    buildSettings->AddAttribute("SDKROOT", 
                                this->CreateString(sysroot));
    std::string archString;
    for( std::vector<std::string>::iterator i = 
           this->Architectures.begin();
         i != this->Architectures.end(); ++i)
      {
      archString += *i;
      archString += " ";
      }
    buildSettings->AddAttribute("ARCHS", 
                                this->CreateString(archString.c_str()));
    if(!flagsUsed && sysrootDefault &&
       strcmp(sysroot, sysrootDefault) != 0)
      {
      buildSettings->AddAttribute("SDKROOT", 
                                  this->CreateString(sysroot));
      }
    }
  if(deploymentTarget && *deploymentTarget)
    {
    buildSettings->AddAttribute("MACOSX_DEPLOYMENT_TARGET",
                                this->CreateString(deploymentTarget));
    }

  // Put this last so it can override existing settings
  // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
  {
    std::vector<std::string> vars = this->CurrentMakefile->GetDefinitions();
    for(std::vector<std::string>::const_iterator i = vars.begin();
        i != vars.end(); ++i)
    {
      if(i->find("CMAKE_XCODE_ATTRIBUTE_") == 0)
      {
        buildSettings->AddAttribute(i->substr(22).c_str(),
          this->CreateString(
            this->CurrentMakefile->GetDefinition(i->c_str())));
      }
    }
  }

  std::string symroot = root->GetMakefile()->GetCurrentOutputDirectory();
  symroot += "/build";
  buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot.c_str()));

  for( std::vector<cmXCodeObject*>::iterator i = configs.begin();
       i != configs.end(); ++i)
    {
    (*i)->AddAttribute("buildSettings", buildSettings);
    }

  this->RootObject->AddAttribute("buildConfigurationList", 
                             this->CreateObjectReference(configlist));

  std::vector<cmXCodeObject*> targets;
  for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
      i != generators.end(); ++i)
    {
    if(!this->IsExcluded(root, *i))
      {
      this->CreateXCodeTargets(*i, targets);
      }
    }
  // loop over all targets and add link and depend info
  for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
      i != targets.end(); ++i)
    {
    cmXCodeObject* t = *i;
    this->AddDependAndLinkInformation(t);
    }
  // now create xcode depend hack makefile
  this->CreateXCodeDependHackTarget(targets);
  // now add all targets to the root object
  cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST);
  for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
      i != targets.end(); ++i)
    { 
    cmXCodeObject* t = *i;
    allTargets->AddObject(t);
    cmXCodeObject* productRef = t->GetObject("productReference");
    if(productRef)
      {
      productGroupChildren->AddObject(productRef->GetObject());
      }
    }
  this->RootObject->AddAttribute("targets", allTargets);
}

//----------------------------------------------------------------------------
void 
cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
  std::vector<cmXCodeObject*>& targets)
{ 
  cmGeneratedFileStream 
    makefileStream(this->CurrentXCodeHackMakefile.c_str());
  if(!makefileStream)
    {
    cmSystemTools::Error("Could not create",
                         this->CurrentXCodeHackMakefile.c_str());
    return;
    }
  makefileStream.SetCopyIfDifferent(true);
  // one more pass for external depend information not handled
  // correctly by xcode
  makefileStream << "# DO NOT EDIT\n";
  makefileStream << "# This makefile makes sure all linkable targets are\n";
  makefileStream << "# up-to-date with anything they link to, avoiding a "
    "bug in XCode 1.5\n";
  for(std::vector<std::string>::const_iterator
        ct = this->CurrentConfigurationTypes.begin();
      ct != this->CurrentConfigurationTypes.end(); ++ct)
    {
    if(this->XcodeVersion < 21 || ct->empty())
      {
      makefileStream << "all: ";
      }
    else
      {
      makefileStream << "all." << *ct << ": ";
      }
    const char* configName = 0;
    if(!ct->empty())
      {
      configName = ct->c_str();
      }
    for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
        i != targets.end(); ++i)
      {
      cmXCodeObject* target = *i;
      cmTarget* t =target->GetTarget();
      if(t->GetType() == cmTarget::EXECUTABLE ||
         t->GetType() == cmTarget::SHARED_LIBRARY ||
         t->GetType() == cmTarget::MODULE_LIBRARY)
        {
        std::string tfull = t->GetFullPath(configName);
        makefileStream << "\\\n\t" <<
          this->ConvertToRelativeForMake(tfull.c_str());
        }
      }
    makefileStream << "\n\n"; 
    }
  makefileStream 
    << "# For each target create a dummy rule "
    "so the target does not have to exist\n";
  std::set<cmStdString> emitted;
  for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
      i != targets.end(); ++i)
    {
    cmXCodeObject* target = *i;
    std::map<cmStdString, cmXCodeObject::StringVec> const& deplibs =
      target->GetDependLibraries();
    for(std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator ci 
          = deplibs.begin(); ci != deplibs.end(); ++ci)
      {
      for(cmXCodeObject::StringVec::const_iterator d = ci->second.begin();
          d != ci->second.end(); ++d)
        {
        if(emitted.insert(*d).second)
          {
          makefileStream << 
            this->ConvertToRelativeForMake(d->c_str()) << ":\n";
          }
        }
      }
    }
  makefileStream << "\n\n";

  // Write rules to help Xcode relink things at the right time.
  makefileStream << 
    "# Rules to remove targets that are older than anything to which they\n"
    "# link.  This forces Xcode to relink the targets from scratch.  It\n"
    "# does not seem to check these dependencies itself.\n";  
  for(std::vector<std::string>::const_iterator
        ct = this->CurrentConfigurationTypes.begin();
      ct != this->CurrentConfigurationTypes.end(); ++ct)
    {
    const char* configName = 0;
    if(!ct->empty())
      {
      configName = ct->c_str();
      }
    for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
        i != targets.end(); ++i)
      {
      cmXCodeObject* target = *i;
      cmTarget* t =target->GetTarget();
      if(t->GetType() == cmTarget::EXECUTABLE ||
         t->GetType() == cmTarget::SHARED_LIBRARY ||
         t->GetType() == cmTarget::MODULE_LIBRARY)
        {
        // Create a rule for this target.
        std::string tfull = t->GetFullPath(configName);
        makefileStream << this->ConvertToRelativeForMake(tfull.c_str()) 
                       << ":";

        // List dependencies if any exist.
        std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
          x = target->GetDependLibraries().find(*ct);
        if(x != target->GetDependLibraries().end())
          {
          std::vector<cmStdString> const& deplibs = x->second;
          for(std::vector<cmStdString>::const_iterator d = deplibs.begin();
              d != deplibs.end(); ++d)
            {
            makefileStream << "\\\n\t" << 
              this->ConvertToRelativeForMake(d->c_str());
            }
          }
        // Write the action to remove the target if it is out of date.
        makefileStream << "\n";
        makefileStream << "\t/bin/rm -f "
                       << this->ConvertToRelativeForMake(tfull.c_str())
                       << "\n";
        // if building for more than one architecture
        // 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/";
          for( std::vector<std::string>::iterator arch = 
                 this->Architectures.begin();
               arch != this->Architectures.end(); ++arch)
            {
            std::string universalFile = universal;
            universalFile += *arch;
            universalFile += "/";
            universalFile += t->GetFullName(configName);
            makefileStream << "\t/bin/rm -f "
                           << 
              this->ConvertToRelativeForMake(universalFile.c_str())
                           << "\n";
            }
          }
        makefileStream << "\n\n";
        }
      }
    }
}

//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
                                           std::vector<cmLocalGenerator*>& 
                                           generators)
{
  if(generators.size() == 0)
    {
    return;
    }
  // Skip local generators that are excluded from this project.
  for(std::vector<cmLocalGenerator*>::iterator g = generators.begin();
      g != generators.end(); ++g)
    {
    if(this->IsExcluded(root, *g))
      {
      continue;
      }
    }

  this->CreateXCodeObjects(root,
                           generators);
  std::string xcodeDir = root->GetMakefile()->GetStartOutputDirectory();
  xcodeDir += "/";
  xcodeDir += root->GetMakefile()->GetProjectName();
  xcodeDir += ".xcode";
  if(this->XcodeVersion > 20)
    {
    xcodeDir += "proj";
    }
  cmSystemTools::MakeDirectory(xcodeDir.c_str());
  std::string xcodeProjFile = xcodeDir + "/project.pbxproj";
  cmGeneratedFileStream fout(xcodeProjFile.c_str());
  fout.SetCopyIfDifferent(true);
  if(!fout)
    {
    return;
    }
  this->WriteXCodePBXProj(fout, root, generators);
  this->ClearXCodeObjects();
}

//----------------------------------------------------------------------------
void 
cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
                                          cmLocalGenerator* ,
                                          std::vector<cmLocalGenerator*>& )
{
  fout << "// !$*UTF8*$!\n";
  fout << "{\n";
  cmXCodeObject::Indent(1, fout);
  fout << "archiveVersion = 1;\n";
  cmXCodeObject::Indent(1, fout);
  fout << "classes = {\n";
  cmXCodeObject::Indent(1, fout);
  fout << "};\n";
  cmXCodeObject::Indent(1, fout);
  if(this->XcodeVersion >= 21)
    {
    if (this->XcodeVersion >= 31)
      fout << "objectVersion = 45;\n";
    else if (this->XcodeVersion >= 30)
      fout << "objectVersion = 44;\n";
    else
      fout << "objectVersion = 42;\n";
    cmXCode21Object::PrintList(this->XCodeObjects, fout);
    }
  else
    {
    fout << "objectVersion = 39;\n";
    cmXCodeObject::PrintList(this->XCodeObjects, fout);
    }
  cmXCodeObject::Indent(1, fout);
  fout << "rootObject = " << this->RootObject->GetId() << ";\n";
  fout << "}\n";
}

//----------------------------------------------------------------------------
const char* cmGlobalXCodeGenerator::GetCMakeCFGInitDirectory()
{
  return this->XcodeVersion >= 21? "$(CONFIGURATION)" : ".";
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
  const
{
  entry.Name = this->GetName();
  entry.Brief = "Generate XCode project files.";
  entry.Full = "";
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
{
  if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
    {
    return cmSystemTools::ConvertToOutputPath(p);
    }
  else
    {
    std::string ret = 
      this->CurrentLocalGenerator->
        ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p);
    return cmSystemTools::ConvertToOutputPath(ret.c_str());
    }
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
{
  if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
    {
    return cmSystemTools::ConvertToOutputPath(p);
    }
  else
    {
    std::string ret = 
      this->CurrentLocalGenerator->
        ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
    return cmSystemTools::ConvertToOutputPath(ret.c_str());
    }
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
{
  // We force conversion because Xcode breakpoints do not work unless
  // they are in a file named relative to the source tree.
  return this->CurrentLocalGenerator->
    ConvertToRelativePath(this->ProjectSourceDirectoryComponents, p, true);
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p)
{
  return this->CurrentLocalGenerator->
    ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p)
{
  std::string ret = p;
  if(ret.find(' ') != ret.npos)
    {
    std::string t = ret;
    ret = "\"";
    ret += t;
    ret += "\"";
    }
  return ret;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::
GetTargetObjectFileDirectories(cmTarget* target,
                               std::vector<std::string>& 
                               dirs)
{
  std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
  dir += "/";
  dir += this->CurrentMakefile->GetProjectName();
  dir += ".build/";
  dir += this->GetCMakeCFGInitDirectory();
  dir += "/";
  dir += target->GetName();
  dir += ".build/Objects-normal/";
  std::string dirsave = dir;
  if(this->Architectures.size())
    {
    for(std::vector<std::string>::iterator i = this->Architectures.begin(); 
        i != this->Architectures.end(); ++i)
      {
      dir += *i;
      dirs.push_back(dir);
      dir = dirsave;
      }
    }
  else
    {
    dirs.push_back(dir);
    }
}

//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator
::AppendDirectoryForConfig(const char* prefix,
                           const char* config,
                           const char* suffix,
                           std::string& dir)
{
  if(this->XcodeVersion > 20)
    {
    if(config)
      {
      dir += prefix;
      dir += config;
      dir += suffix;
      }
    }
}

//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::LookupFlags(const char* varNamePrefix,
                                                const char* varNameLang,
                                                const char* varNameSuffix,
                                                const char* default_flags)
{
  if(varNameLang)
    {
    std::string varName = varNamePrefix;
    varName += varNameLang;
    varName += varNameSuffix;
    if(const char* varValue =
       this->CurrentMakefile->GetDefinition(varName.c_str()))
      {
      if(*varValue)
        {
        return varValue;
        }
      }
    }
  return default_flags;
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
                                           const char* defines_list,
                                           bool dflag)
{
  // Skip this if there are no definitions.
  if(!defines_list)
    {
    return;
    }

  // Expand the list of definitions.
  std::vector<std::string> defines;
  cmSystemTools::ExpandListArgument(defines_list, defines);

  // Store the definitions in the string.
  this->AppendDefines(defs, defines, dflag);
}

//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
                                      std::vector<std::string> const& defines,
                                      bool dflag)
{
  // GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions.
  std::string def;
  for(std::vector<std::string>::const_iterator di = defines.begin();
      di != defines.end(); ++di)
    {
    // Start with -D if requested.
    def = dflag? "-D": "";
    def += *di;

    // Append the flag with needed escapes.
    std::string tmp;
    this->AppendFlag(tmp, def);
    defs.Add(tmp.c_str());
    }
}

//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
                                        std::string const& flag)
{
  // Short-circuit for an empty flag.
  if(flag.empty())
    {
    return;
    }

  // Separate from previous flags.
  if(!flags.empty())
    {
    flags += " ";
    }

  // Check if the flag needs quoting.
  bool quoteFlag =
    flag.find_first_of("`~!@#$%^&*()+={}[]|:;\"'<>,.? ") != flag.npos;

  // We escape a flag as follows:
  //   - Place each flag in single quotes ''
  //   - Escape a single quote as \\'
  //   - Escape a backslash as \\\\ since it itself is an escape
  // Note that in the code below we need one more level of escapes for
  // C string syntax in this source file.
  //
  // The final level of escaping is done when the string is stored
  // into the project file by cmXCodeObject::PrintString.

  if(quoteFlag)
    {
    // Open single quote.
    flags += "'";
    }

  // Flag value with escaped quotes and backslashes.
  for(const char* c = flag.c_str(); *c; ++c)
    {
    if(*c == '\'')
      {
      flags += "\\\\'";
      }
    else if(*c == '\\')
      {
      flags += "\\\\\\\\";
      }
    else
      {
      flags += *c;
      }
    }

  if(quoteFlag)
    {
    // Close single quote.
    flags += "'";
    }
}

//----------------------------------------------------------------------------
std::string
cmGlobalXCodeGenerator::ComputeInfoPListLocation(cmTarget& target)
{
  std::string plist = target.GetMakefile()->GetCurrentOutputDirectory();
  plist += cmake::GetCMakeFilesDirectory();
  plist += "/";
  plist += target.GetName();
  plist += ".dir/Info.plist";
  return plist;
}

//----------------------------------------------------------------------------
// Return true if the generated build tree may contain multiple builds.
// i.e. "Can I build Debug and Release in the same tree?"
bool cmGlobalXCodeGenerator::IsMultiConfig()
{
  // Old Xcode 1.5 is single config:
  if(this->XcodeVersion == 15)
    {
    return false;
    }

  // Newer Xcode versions are multi config:
  return true;
}
