Imported Upstream version 2.8.12.2
[platform/upstream/cmake.git] / Source / cmGlobalXCodeGenerator.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmGlobalXCodeGenerator.h"
13 #include "cmLocalXCodeGenerator.h"
14 #include "cmMakefile.h"
15 #include "cmXCodeObject.h"
16 #include "cmXCode21Object.h"
17 #include "cmake.h"
18 #include "cmGeneratedFileStream.h"
19 #include "cmComputeLinkInformation.h"
20 #include "cmSourceFile.h"
21 #include "cmCustomCommandGenerator.h"
22 #include "cmGeneratorTarget.h"
23 #include "cmGlobalGeneratorFactory.h"
24
25 #include <cmsys/auto_ptr.hxx>
26
27 //----------------------------------------------------------------------------
28 #if defined(CMAKE_BUILD_WITH_CMAKE)
29 #include "cmXMLParser.h"
30
31 // parse the xml file storing the installed version of Xcode on
32 // the machine
33 class cmXcodeVersionParser : public cmXMLParser
34 {
35 public:
36   cmXcodeVersionParser(): Version("1.5") {}
37   void StartElement(const char* , const char** )
38     {
39       this->Data = "";
40     }
41   void EndElement(const char* name)
42     {
43       if(strcmp(name, "key") == 0)
44         {
45         this->Key = this->Data;
46         }
47       else if(strcmp(name, "string") == 0)
48         {
49         if(this->Key == "CFBundleShortVersionString")
50           {
51           this->Version = this->Data;
52           }
53         }
54     }
55   void CharacterDataHandler(const char* data, int length)
56     {
57       this->Data.append(data, length);
58     }
59   std::string Version;
60   std::string Key;
61   std::string Data;
62 };
63 #endif
64
65 // Builds either an object list or a space-separated string from the
66 // given inputs.
67 class cmGlobalXCodeGenerator::BuildObjectListOrString
68 {
69   cmGlobalXCodeGenerator *Generator;
70   cmXCodeObject *Group;
71   bool Empty;
72   std::string String;
73
74 public:
75   BuildObjectListOrString(cmGlobalXCodeGenerator *gen, bool buildObjectList)
76     : Generator(gen), Group(0), Empty(true)
77     {
78     if (buildObjectList)
79       {
80       this->Group = this->Generator->CreateObject(cmXCodeObject::OBJECT_LIST);
81       }
82     }
83
84   bool IsEmpty() const { return this->Empty; }
85
86   void Add(const char *newString)
87     {
88     this->Empty = false;
89
90     if (this->Group)
91       {
92       this->Group->AddObject(this->Generator->CreateString(newString));
93       }
94     else
95       {
96       this->String += newString;
97       this->String += ' ';
98       }
99     }
100
101   const std::string &GetString() const { return this->String; }
102
103   cmXCodeObject *CreateList()
104     {
105     if (this->Group)
106       {
107       return this->Group;
108       }
109     else
110       {
111       return this->Generator->CreateString(this->String.c_str());
112       }
113     }
114 };
115
116 class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory
117 {
118 public:
119   virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const;
120
121   virtual void GetDocumentation(cmDocumentationEntry& entry) const {
122     cmGlobalXCodeGenerator::GetDocumentation(entry); }
123
124   virtual void GetGenerators(std::vector<std::string>& names) const {
125     names.push_back(cmGlobalXCodeGenerator::GetActualName()); }
126 };
127
128 //----------------------------------------------------------------------------
129 cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
130 {
131   this->VersionString = version;
132
133   // Compute an integer form of the version number.
134   unsigned int v[2] = {0,0};
135   sscanf(this->VersionString.c_str(), "%u.%u", &v[0], &v[1]);
136   this->XcodeVersion = 10*v[0] + v[1];
137
138   this->FindMakeProgramFile = "CMakeFindXCode.cmake";
139   this->RootObject = 0;
140   this->MainGroupChildren = 0;
141   this->SourcesGroupChildren = 0;
142   this->ResourcesGroupChildren = 0;
143   this->CurrentMakefile = 0;
144   this->CurrentLocalGenerator = 0;
145 }
146
147 //----------------------------------------------------------------------------
148 cmGlobalGeneratorFactory* cmGlobalXCodeGenerator::NewFactory()
149 {
150   return new Factory;
151 }
152
153 //----------------------------------------------------------------------------
154 cmGlobalGenerator* cmGlobalXCodeGenerator::Factory
155 ::CreateGlobalGenerator(const char* name) const
156 {
157   if (strcmp(name, GetActualName()))
158     return 0;
159 #if defined(CMAKE_BUILD_WITH_CMAKE)
160   cmXcodeVersionParser parser;
161   std::string versionFile;
162   {
163   std::string out;
164   std::string::size_type pos;
165   if(cmSystemTools::RunSingleCommand("xcode-select --print-path", &out, 0, 0,
166                                      cmSystemTools::OUTPUT_NONE) &&
167      (pos = out.find(".app/"), pos != out.npos))
168     {
169     versionFile = out.substr(0, pos+5)+"Contents/version.plist";
170     }
171   }
172   if(!versionFile.empty() && cmSystemTools::FileExists(versionFile.c_str()))
173     {
174     parser.ParseFile(versionFile.c_str());
175     }
176   else if (cmSystemTools::FileExists(
177              "/Applications/Xcode.app/Contents/version.plist"))
178     {
179     parser.ParseFile
180       ("/Applications/Xcode.app/Contents/version.plist");
181     }
182   else
183     {
184     parser.ParseFile
185       ("/Developer/Applications/Xcode.app/Contents/version.plist");
186     }
187   cmsys::auto_ptr<cmGlobalXCodeGenerator>
188     gg(new cmGlobalXCodeGenerator(parser.Version));
189   if (gg->XcodeVersion == 20)
190     {
191     cmSystemTools::Message("Xcode 2.0 not really supported by cmake, "
192                            "using Xcode 15 generator\n");
193     gg->XcodeVersion = 15;
194     }
195   return gg.release();
196 #else
197   std::cerr << "CMake should be built with cmake to use Xcode, "
198     "default to Xcode 1.5\n";
199   return new cmGlobalXCodeGenerator;
200 #endif
201 }
202
203 //----------------------------------------------------------------------------
204 bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts)
205 {
206   if(this->XcodeVersion >= 30)
207     {
208     this->PlatformToolset = ts;
209     return true;
210     }
211   else
212     {
213     return cmGlobalGenerator::SetGeneratorToolset(ts);
214     }
215 }
216
217 //----------------------------------------------------------------------------
218 void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
219                                             lang,
220                                             cmMakefile * mf, bool optional)
221 {
222   mf->AddDefinition("XCODE","1");
223   mf->AddDefinition("XCODE_VERSION", this->VersionString.c_str());
224   if(this->XcodeVersion == 15)
225     {
226     }
227   else
228     {
229     if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
230       {
231       mf->AddCacheDefinition(
232         "CMAKE_CONFIGURATION_TYPES",
233         "Debug;Release;MinSizeRel;RelWithDebInfo",
234         "Semicolon separated list of supported configuration types, "
235         "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
236         "anything else will be ignored.",
237         cmCacheManager::STRING);
238       }
239     }
240   mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
241   if(!this->PlatformToolset.empty())
242     {
243     mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
244                       this->PlatformToolset.c_str());
245     }
246   this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
247     const char* osxArch =
248       mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
249   const char* sysroot =
250       mf->GetDefinition("CMAKE_OSX_SYSROOT");
251   if(osxArch && sysroot)
252     {
253     this->Architectures.clear();
254     cmSystemTools::ExpandListArgument(std::string(osxArch),
255                                       this->Architectures);
256     }
257 }
258
259 //----------------------------------------------------------------------------
260 std::string cmGlobalXCodeGenerator
261 ::GenerateBuildCommand(const char* makeProgram,
262                        const char *projectName,
263                        const char *projectDir,
264                        const char* additionalOptions,
265                        const char *targetName,
266                        const char* config,
267                        bool ignoreErrors,
268                        bool)
269 {
270   // Config is not used yet
271   (void) ignoreErrors;
272   (void) projectDir;
273
274   // now build the test
275   if(makeProgram == 0 || !strlen(makeProgram))
276     {
277     cmSystemTools::Error(
278       "Generator cannot find the appropriate make command.");
279     return "";
280     }
281   std::string makeCommand =
282     cmSystemTools::ConvertToOutputPath(makeProgram);
283   std::string lowerCaseCommand = makeCommand;
284   cmSystemTools::LowerCase(lowerCaseCommand);
285
286   makeCommand += " -project ";
287   makeCommand += projectName;
288   makeCommand += ".xcode";
289   if(this->XcodeVersion > 20)
290     {
291     makeCommand += "proj";
292     }
293
294   bool clean = false;
295   if ( targetName && strcmp(targetName, "clean") == 0 )
296     {
297     clean = true;
298     targetName = "ALL_BUILD";
299     }
300   if(clean)
301     {
302     makeCommand += " clean";
303     }
304   else
305     {
306     makeCommand += " build";
307     }
308   makeCommand += " -target ";
309   // if it is a null string for config don't use it
310   if(config && *config == 0)
311     {
312     config = 0;
313     }
314   if (targetName && strlen(targetName))
315     {
316     makeCommand += targetName;
317     }
318   else
319     {
320     makeCommand += "ALL_BUILD";
321     }
322   if(this->XcodeVersion == 15)
323     {
324     makeCommand += " -buildstyle Development ";
325     }
326   else
327     {
328     makeCommand += " -configuration ";
329     makeCommand += config?config:"Debug";
330     }
331   if ( additionalOptions )
332     {
333     makeCommand += " ";
334     makeCommand += additionalOptions;
335     }
336   return makeCommand;
337 }
338
339 //----------------------------------------------------------------------------
340 ///! Create a local generator appropriate to this Global Generator
341 cmLocalGenerator *cmGlobalXCodeGenerator::CreateLocalGenerator()
342 {
343   cmLocalGenerator *lg = new cmLocalXCodeGenerator;
344   lg->SetGlobalGenerator(this);
345   return lg;
346 }
347
348 //----------------------------------------------------------------------------
349 void cmGlobalXCodeGenerator::Generate()
350 {
351   std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
352   // make sure extra targets are added before calling
353   // the parent generate which will call trace depends
354   for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
355     {
356     cmLocalGenerator* root = it->second[0];
357     this->SetGenerationRoot(root);
358     // add ALL_BUILD, INSTALL, etc
359     this->AddExtraTargets(root, it->second);
360     }
361   this->ForceLinkerLanguages();
362   this->cmGlobalGenerator::Generate();
363   if(cmSystemTools::GetErrorOccuredFlag())
364     {
365     return;
366     }
367   for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
368     {
369     cmLocalGenerator* root = it->second[0];
370     this->SetGenerationRoot(root);
371     // now create the project
372     this->OutputXCodeProject(root, it->second);
373     }
374 }
375
376 //----------------------------------------------------------------------------
377 void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
378 {
379   this->CurrentProject = root->GetMakefile()->GetProjectName();
380   this->SetCurrentLocalGenerator(root);
381   cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentDirectory(),
382                            this->ProjectSourceDirectoryComponents);
383   cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentOutputDirectory(),
384                            this->ProjectOutputDirectoryComponents);
385
386   this->CurrentXCodeHackMakefile =
387     root->GetMakefile()->GetCurrentOutputDirectory();
388   this->CurrentXCodeHackMakefile += "/CMakeScripts";
389   cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile.c_str());
390   this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
391 }
392
393 //----------------------------------------------------------------------------
394 std::string
395 cmGlobalXCodeGenerator::PostBuildMakeTarget(std::string const& tName,
396                                             std::string const& configName)
397 {
398   std::string target = tName;
399   cmSystemTools::ReplaceString(target, " ", "_");
400   std::string out = "PostBuild." + target;
401   if(this->XcodeVersion > 20)
402     {
403     out += "." + configName;
404     }
405   return out;
406 }
407
408 //----------------------------------------------------------------------------
409 #define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
410
411 //----------------------------------------------------------------------------
412 void
413 cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
414                                         std::vector<cmLocalGenerator*>& gens)
415 {
416   cmMakefile* mf = root->GetMakefile();
417
418   // Add ALL_BUILD
419   const char* no_working_directory = 0;
420   std::vector<std::string> no_depends;
421   mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
422                         no_working_directory,
423                         "echo", "Build all projects");
424   cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
425
426   // Refer to the main build configuration file for easy editing.
427   std::string listfile = mf->GetStartDirectory();
428   listfile += "/";
429   listfile += "CMakeLists.txt";
430   allbuild->AddSource(listfile.c_str());
431
432   // Add XCODE depend helper
433   std::string dir = mf->GetCurrentOutputDirectory();
434   cmCustomCommandLine makeHelper;
435   if(this->XcodeVersion < 50)
436     {
437     makeHelper.push_back("make");
438     makeHelper.push_back("-C");
439     makeHelper.push_back(dir.c_str());
440     makeHelper.push_back("-f");
441     makeHelper.push_back(this->CurrentXCodeHackMakefile.c_str());
442     makeHelper.push_back(""); // placeholder, see below
443     }
444
445   // Add ZERO_CHECK
446   bool regenerate = !mf->IsOn("CMAKE_SUPPRESS_REGENERATION");
447   if (regenerate)
448     {
449     this->CreateReRunCMakeFile(root, gens);
450     std::string file = this->ConvertToRelativeForMake(
451       this->CurrentReRunCMakeMakefile.c_str());
452     cmSystemTools::ReplaceString(file, "\\ ", " ");
453     mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true, no_depends,
454                           no_working_directory,
455                           "make", "-f", file.c_str());
456     }
457
458   // now make the allbuild depend on all the non-utility targets
459   // in the project
460   for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
461       i != gens.end(); ++i)
462     {
463     cmLocalGenerator* lg = *i;
464     if(this->IsExcluded(root, *i))
465       {
466       continue;
467       }
468
469     cmTargets& tgts = lg->GetMakefile()->GetTargets();
470     for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
471       {
472       cmTarget& target = l->second;
473
474       if (regenerate && (l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET))
475         {
476         target.AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
477         }
478
479       // make all exe, shared libs and modules
480       // run the depend check makefile as a post build rule
481       // this will make sure that when the next target is built
482       // things are up-to-date
483       if(!makeHelper.empty() &&
484          (target.GetType() == cmTarget::EXECUTABLE ||
485 // Nope - no post-build for OBJECT_LIRBRARY
486 //          target.GetType() == cmTarget::OBJECT_LIBRARY ||
487           target.GetType() == cmTarget::STATIC_LIBRARY ||
488           target.GetType() == cmTarget::SHARED_LIBRARY ||
489           target.GetType() == cmTarget::MODULE_LIBRARY))
490         {
491         makeHelper[makeHelper.size()-1] = // fill placeholder
492           this->PostBuildMakeTarget(target.GetName(), "$(CONFIGURATION)");
493         cmCustomCommandLines commandLines;
494         commandLines.push_back(makeHelper);
495         lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
496                                                     no_depends,
497                                                     commandLines,
498                                                     cmTarget::POST_BUILD,
499                                                     "Depend check for xcode",
500                                                     dir.c_str());
501         }
502
503       if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
504         {
505         allbuild->AddUtility(target.GetName());
506         }
507
508       // Refer to the build configuration file for easy editing.
509       listfile = lg->GetMakefile()->GetStartDirectory();
510       listfile += "/";
511       listfile += "CMakeLists.txt";
512       target.AddSource(listfile.c_str());
513       }
514     }
515 }
516
517 //----------------------------------------------------------------------------
518 void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
519   cmLocalGenerator* root, std::vector<cmLocalGenerator*> const& gens)
520 {
521   cmMakefile* mf = root->GetMakefile();
522   std::vector<std::string> lfiles;
523   for(std::vector<cmLocalGenerator*>::const_iterator gi = gens.begin();
524       gi != gens.end(); ++gi)
525     {
526     std::vector<std::string> const& lf = (*gi)->GetMakefile()->GetListFiles();
527     lfiles.insert(lfiles.end(), lf.begin(), lf.end());
528     }
529
530   // sort the array
531   std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
532   std::vector<std::string>::iterator new_end =
533     std::unique(lfiles.begin(), lfiles.end());
534   lfiles.erase(new_end, lfiles.end());
535   this->CurrentReRunCMakeMakefile = mf->GetStartOutputDirectory();
536   this->CurrentReRunCMakeMakefile += "/CMakeScripts";
537   cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str());
538   this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
539   cmGeneratedFileStream makefileStream
540     (this->CurrentReRunCMakeMakefile.c_str());
541   makefileStream.SetCopyIfDifferent(true);
542   makefileStream << "# Generated by CMake, DO NOT EDIT\n";
543   std::string checkCache = mf->GetHomeOutputDirectory();
544   checkCache += "/";
545   checkCache += cmake::GetCMakeFilesDirectoryPostSlash();
546   checkCache += "cmake.check_cache";
547   makefileStream << this->ConvertToRelativeForMake(checkCache.c_str())
548                  << ": ";
549   for(std::vector<std::string>::const_iterator i = lfiles.begin();
550       i !=  lfiles.end(); ++i)
551     {
552     makefileStream << "\\\n" << this->ConvertToRelativeForMake(i->c_str());
553     }
554   std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
555   makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str())
556                  << " -H" << this->ConvertToRelativeForMake(
557                    mf->GetHomeDirectory())
558                  << " -B" << this->ConvertToRelativeForMake(
559                    mf->GetHomeOutputDirectory()) << "\n";
560 }
561
562 //----------------------------------------------------------------------------
563 void cmGlobalXCodeGenerator::ClearXCodeObjects()
564 {
565   this->TargetDoneSet.clear();
566   for(unsigned int i = 0; i < this->XCodeObjects.size(); ++i)
567     {
568     delete this->XCodeObjects[i];
569     }
570   this->XCodeObjects.clear();
571   this->XCodeObjectIDs.clear();
572   this->GroupMap.clear();
573   this->GroupNameMap.clear();
574   this->TargetGroup.clear();
575   this->FileRefs.clear();
576 }
577
578 //----------------------------------------------------------------------------
579 void cmGlobalXCodeGenerator::addObject(cmXCodeObject *obj)
580 {
581   if(obj->GetType() == cmXCodeObject::OBJECT)
582     {
583     cmStdString id = obj->GetId();
584
585     // If this is a duplicate id, it's an error:
586     //
587     if(this->XCodeObjectIDs.count(id))
588       {
589       cmSystemTools::Error(
590         "Xcode generator: duplicate object ids not allowed");
591       }
592
593     this->XCodeObjectIDs.insert(id);
594     }
595
596   this->XCodeObjects.push_back(obj);
597 }
598
599 //----------------------------------------------------------------------------
600 cmXCodeObject*
601 cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
602 {
603   cmXCodeObject* obj;
604   if(this->XcodeVersion == 15)
605     {
606     obj = new cmXCodeObject(ptype, cmXCodeObject::OBJECT);
607     }
608   else
609     {
610     obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
611     }
612   this->addObject(obj);
613   return obj;
614 }
615
616 //----------------------------------------------------------------------------
617 cmXCodeObject*
618 cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
619 {
620   cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
621   this->addObject(obj);
622   return obj;
623 }
624
625 //----------------------------------------------------------------------------
626 cmXCodeObject*
627 cmGlobalXCodeGenerator::CreateString(const char* s)
628 {
629   cmXCodeObject* obj = this->CreateObject(cmXCodeObject::STRING);
630   obj->SetString(s);
631   return obj;
632 }
633
634 //----------------------------------------------------------------------------
635 cmXCodeObject* cmGlobalXCodeGenerator
636 ::CreateObjectReference(cmXCodeObject* ref)
637 {
638   cmXCodeObject* obj = this->CreateObject(cmXCodeObject::OBJECT_REF);
639   obj->SetObject(ref);
640   return obj;
641 }
642
643 //----------------------------------------------------------------------------
644 cmStdString
645 GetGroupMapKeyFromPath(cmTarget& cmtarget, const std::string& fullpath)
646 {
647   cmStdString key(cmtarget.GetName());
648   key += "-";
649   key += fullpath;
650   return key;
651 }
652
653 //----------------------------------------------------------------------------
654 cmStdString
655 GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
656 {
657   return GetGroupMapKeyFromPath(cmtarget, sf->GetFullPath());
658 }
659
660 //----------------------------------------------------------------------------
661 cmXCodeObject*
662 cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
663   const std::string &fullpath,
664   cmTarget& cmtarget,
665   const std::string &lang)
666 {
667   // Using a map and the full path guarantees that we will always get the same
668   // fileRef object for any given full path.
669   //
670   cmXCodeObject* fileRef =
671     this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang);
672
673   cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
674   buildFile->SetComment(fileRef->GetComment());
675   buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
676
677   return buildFile;
678 }
679
680 //----------------------------------------------------------------------------
681 cmXCodeObject*
682 cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
683                                               cmSourceFile* sf,
684                                               cmTarget& cmtarget)
685 {
686   // Add flags from target and source file properties.
687   std::string flags;
688   const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
689   switch(this->CurrentLocalGenerator->GetFortranFormat(srcfmt))
690     {
691     case cmLocalGenerator::FortranFormatFixed: flags="-fixed "+flags; break;
692     case cmLocalGenerator::FortranFormatFree: flags="-free "+flags; break;
693     default: break;
694     }
695   lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS"));
696
697   // Add per-source definitions.
698   BuildObjectListOrString flagsBuild(this, false);
699   this->AppendDefines(flagsBuild,
700                       sf->GetProperty("COMPILE_DEFINITIONS"), true);
701   if (!flagsBuild.IsEmpty())
702     {
703     if (flags.size())
704       {
705       flags += ' ';
706       }
707     flags += flagsBuild.GetString();
708     }
709
710   const char* lang =
711     this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
712   if (!lang)
713     {
714     lang = "";
715     }
716
717   cmXCodeObject* buildFile =
718     this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang);
719   cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
720
721   cmXCodeObject* settings =
722     this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
723   settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags.c_str()));
724
725   // Is this a resource file in this target? Add it to the resources group...
726   //
727   cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
728   bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);
729
730   // Is this a "private" or "public" framework header file?
731   // Set the ATTRIBUTES attribute appropriately...
732   //
733   if(cmtarget.IsFrameworkOnApple())
734     {
735     if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
736       {
737       cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
738       attrs->AddObject(this->CreateString("Private"));
739       settings->AddAttribute("ATTRIBUTES", attrs);
740       isResource = true;
741       }
742     else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
743       {
744       cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
745       attrs->AddObject(this->CreateString("Public"));
746       settings->AddAttribute("ATTRIBUTES", attrs);
747       isResource = true;
748       }
749     }
750
751   // Add the fileRef to the top level Resources group/folder if it is not
752   // already there.
753   //
754   if(isResource && this->ResourcesGroupChildren &&
755     !this->ResourcesGroupChildren->HasObject(fileRef))
756     {
757     this->ResourcesGroupChildren->AddObject(fileRef);
758     }
759
760   buildFile->AddAttribute("settings", settings);
761   return buildFile;
762 }
763
764 //----------------------------------------------------------------------------
765 std::string
766 GetSourcecodeValueFromFileExtension(const std::string& _ext,
767                                     const std::string& lang)
768 {
769   std::string ext = cmSystemTools::LowerCase(_ext);
770   std::string sourcecode = "sourcecode";
771
772   if(ext == "o")
773     {
774     sourcecode = "compiled.mach-o.objfile";
775     }
776   else if(ext == "xib")
777     {
778     sourcecode = "file.xib";
779     }
780   else if(ext == "storyboard")
781     {
782     sourcecode = "file.storyboard";
783     }
784   else if(ext == "mm")
785     {
786     sourcecode += ".cpp.objcpp";
787     }
788   else if(ext == "m")
789     {
790     sourcecode += ".c.objc";
791     }
792   else if(ext == "xib")
793     {
794     sourcecode += ".file.xib";
795     }
796   else if(ext == "plist")
797     {
798     sourcecode += ".text.plist";
799     }
800   else if(ext == "h")
801     {
802     sourcecode += ".c.h";
803     }
804   else if(ext == "hxx" || ext == "hpp" || ext == "txx"
805     || ext == "pch" || ext == "hh")
806     {
807     sourcecode += ".cpp.h";
808     }
809   else if(ext == "png" || ext == "gif" || ext == "jpg")
810     {
811     sourcecode = "image";
812     }
813   else if(ext == "txt")
814     {
815     sourcecode += ".text";
816     }
817   else if(lang == "CXX")
818     {
819     sourcecode += ".cpp.cpp";
820     }
821   else if(lang == "C")
822     {
823     sourcecode += ".c.c";
824     }
825   else if(lang == "Fortran")
826     {
827     sourcecode += ".fortran.f90";
828     }
829   else if(lang == "ASM")
830     {
831     sourcecode += ".asm";
832     }
833   //else
834   //  {
835   //  // Already specialized above or we leave sourcecode == "sourcecode"
836   //  // which is probably the most correct choice. Extensionless headers,
837   //  // for example... Or file types unknown to Xcode that do not map to a
838   //  // valid explicitFileType value.
839   //  }
840
841   return sourcecode;
842 }
843
844 //----------------------------------------------------------------------------
845 cmXCodeObject*
846 cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
847   const std::string &fullpath,
848   cmTarget& cmtarget,
849   const std::string &lang)
850 {
851   std::string fname = fullpath;
852   cmXCodeObject* fileRef = this->FileRefs[fname];
853   if(!fileRef)
854     {
855     fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
856     std::string comment = fname;
857     fileRef->SetComment(fname.c_str());
858     this->FileRefs[fname] = fileRef;
859     }
860   cmStdString key = GetGroupMapKeyFromPath(cmtarget, fullpath);
861   cmXCodeObject* group = this->GroupMap[key];
862   cmXCodeObject* children = group->GetObject("children");
863   if (!children->HasObject(fileRef))
864     {
865     children->AddObject(fileRef);
866     }
867   fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
868
869   // Compute the extension.
870   std::string ext;
871   std::string realExt =
872     cmSystemTools::GetFilenameLastExtension(fullpath);
873   if(!realExt.empty())
874     {
875     // Extension without the leading '.'.
876     ext = realExt.substr(1);
877     }
878
879   std::string sourcecode = GetSourcecodeValueFromFileExtension(ext, lang);
880   const char* attribute = (sourcecode == "file.storyboard") ?
881                            "lastKnownFileType" :
882                            "explicitFileType";
883   fileRef->AddAttribute(attribute,
884                         this->CreateString(sourcecode.c_str()));
885
886   // Store the file path relative to the top of the source tree.
887   std::string path = this->RelativeToSource(fullpath.c_str());
888   std::string name = cmSystemTools::GetFilenameName(path.c_str());
889   const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())?
890                             "<absolute>" : "SOURCE_ROOT");
891   fileRef->AddAttribute("name", this->CreateString(name.c_str()));
892   fileRef->AddAttribute("path", this->CreateString(path.c_str()));
893   fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
894   if(this->XcodeVersion == 15)
895     {
896     fileRef->AddAttribute("refType", this->CreateString("4"));
897     }
898   return fileRef;
899 }
900
901 //----------------------------------------------------------------------------
902 cmXCodeObject*
903 cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
904                                                  cmTarget& cmtarget)
905 {
906   const char* lang =
907     this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
908   if (!lang)
909     {
910     lang = "";
911     }
912
913   return this->CreateXCodeFileReferenceFromPath(
914     sf->GetFullPath(), cmtarget, lang);
915 }
916
917 //----------------------------------------------------------------------------
918 bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
919 {
920   if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
921      tname == "install" || tname == "package" || tname == "RUN_TESTS" ||
922      tname == CMAKE_CHECK_BUILD_SYSTEM_TARGET )
923     {
924     if(this->TargetDoneSet.find(tname) != this->TargetDoneSet.end())
925       {
926       return true;
927       }
928     this->TargetDoneSet.insert(tname);
929     return false;
930     }
931   return false;
932 }
933
934 //----------------------------------------------------------------------------
935 void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
936 {
937   this->CurrentLocalGenerator = gen;
938   this->CurrentMakefile = gen->GetMakefile();
939   std::string outdir =
940     cmSystemTools::CollapseFullPath(this->CurrentMakefile->
941                                     GetCurrentOutputDirectory());
942   cmSystemTools::SplitPath(outdir.c_str(),
943                            this->CurrentOutputDirectoryComponents);
944
945   // Select the current set of configuration types.
946   this->CurrentConfigurationTypes.clear();
947   this->CurrentMakefile->GetConfigurations(this->CurrentConfigurationTypes);
948   if(this->CurrentConfigurationTypes.empty())
949     {
950     this->CurrentConfigurationTypes.push_back("");
951     }
952 }
953
954 //----------------------------------------------------------------------------
955 struct cmSourceFilePathCompare
956 {
957   bool operator()(cmSourceFile* l, cmSourceFile* r)
958   {
959     return l->GetFullPath() < r->GetFullPath();
960   }
961 };
962
963 //----------------------------------------------------------------------------
964 void
965 cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
966                                            std::vector<cmXCodeObject*>&
967                                            targets)
968 {
969   this->SetCurrentLocalGenerator(gen);
970   cmTargets &tgts = this->CurrentMakefile->GetTargets();
971   for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
972     {
973     cmTarget& cmtarget = l->second;
974
975     // make sure ALL_BUILD, INSTALL, etc are only done once
976     if(this->SpecialTargetEmitted(l->first.c_str()))
977       {
978       continue;
979       }
980
981     if(cmtarget.GetType() == cmTarget::UTILITY ||
982        cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
983       {
984       targets.push_back(this->CreateUtilityTarget(cmtarget));
985       continue;
986       }
987
988     // organize the sources
989     std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
990     std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
991
992     std::vector<cmXCodeObject*> externalObjFiles;
993     std::vector<cmXCodeObject*> headerFiles;
994     std::vector<cmXCodeObject*> resourceFiles;
995     std::vector<cmXCodeObject*> sourceFiles;
996     for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
997         i != classes.end(); ++i)
998       {
999       cmXCodeObject* xsf =
1000         this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
1001                                     *i, cmtarget);
1002       cmXCodeObject* fr = xsf->GetObject("fileRef");
1003       cmXCodeObject* filetype =
1004         fr->GetObject()->GetObject("explicitFileType");
1005
1006       cmTarget::SourceFileFlags tsFlags =
1007         cmtarget.GetTargetSourceFileFlags(*i);
1008
1009       if(strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
1010         {
1011         externalObjFiles.push_back(xsf);
1012         }
1013       else if(this->IsHeaderFile(*i) ||
1014         (tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
1015         (tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
1016         {
1017         headerFiles.push_back(xsf);
1018         }
1019       else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
1020         {
1021         resourceFiles.push_back(xsf);
1022         }
1023       else if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
1024         {
1025         // Include this file in the build if it has a known language
1026         // and has not been listed as an ignored extension for this
1027         // generator.
1028         if(this->CurrentLocalGenerator->GetSourceFileLanguage(**i) &&
1029            !this->IgnoreFile((*i)->GetExtension().c_str()))
1030           {
1031           sourceFiles.push_back(xsf);
1032           }
1033         }
1034       }
1035
1036     if(this->XcodeVersion < 50)
1037       {
1038       // Add object library contents as external objects. (Equivalent to
1039       // the externalObjFiles above, except each one is not a cmSourceFile
1040       // within the target.)
1041       std::vector<std::string> objs;
1042       this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
1043       for(std::vector<std::string>::const_iterator
1044             oi = objs.begin(); oi != objs.end(); ++oi)
1045         {
1046         std::string obj = *oi;
1047         cmXCodeObject* xsf =
1048           this->CreateXCodeSourceFileFromPath(obj, cmtarget, "");
1049         externalObjFiles.push_back(xsf);
1050         }
1051       }
1052
1053     // some build phases only apply to bundles and/or frameworks
1054     bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
1055     bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
1056     bool isCFBundleTarget = cmtarget.IsCFBundleOnApple();
1057
1058     cmXCodeObject* buildFiles = 0;
1059
1060     // create source build phase
1061     cmXCodeObject* sourceBuildPhase = 0;
1062     if (!sourceFiles.empty())
1063       {
1064       sourceBuildPhase =
1065         this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase);
1066       sourceBuildPhase->SetComment("Sources");
1067       sourceBuildPhase->AddAttribute("buildActionMask",
1068                                      this->CreateString("2147483647"));
1069       buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
1070       for(std::vector<cmXCodeObject*>::iterator i = sourceFiles.begin();
1071           i != sourceFiles.end(); ++i)
1072         {
1073         buildFiles->AddObject(*i);
1074         }
1075       sourceBuildPhase->AddAttribute("files", buildFiles);
1076       sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
1077                                      this->CreateString("0"));
1078       }
1079
1080     // create header build phase - only for framework targets
1081     cmXCodeObject* headerBuildPhase = 0;
1082     if (!headerFiles.empty() && isFrameworkTarget)
1083       {
1084       headerBuildPhase =
1085         this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase);
1086       headerBuildPhase->SetComment("Headers");
1087       headerBuildPhase->AddAttribute("buildActionMask",
1088                                      this->CreateString("2147483647"));
1089       buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
1090       for(std::vector<cmXCodeObject*>::iterator i = headerFiles.begin();
1091           i != headerFiles.end(); ++i)
1092         {
1093         buildFiles->AddObject(*i);
1094         }
1095       headerBuildPhase->AddAttribute("files", buildFiles);
1096       headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
1097                                      this->CreateString("0"));
1098       }
1099
1100     // create resource build phase - only for framework or bundle targets
1101     cmXCodeObject* resourceBuildPhase = 0;
1102     if (!resourceFiles.empty() &&
1103         (isFrameworkTarget || isBundleTarget || isCFBundleTarget))
1104       {
1105       resourceBuildPhase =
1106         this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase);
1107       resourceBuildPhase->SetComment("Resources");
1108       resourceBuildPhase->AddAttribute("buildActionMask",
1109                                        this->CreateString("2147483647"));
1110       buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
1111       for(std::vector<cmXCodeObject*>::iterator i = resourceFiles.begin();
1112           i != resourceFiles.end(); ++i)
1113         {
1114         buildFiles->AddObject(*i);
1115         }
1116       resourceBuildPhase->AddAttribute("files", buildFiles);
1117       resourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
1118                                      this->CreateString("0"));
1119       }
1120
1121     // create vector of "non-resource content file" build phases - only for
1122     // framework or bundle targets
1123     std::vector<cmXCodeObject*> contentBuildPhases;
1124     if (isFrameworkTarget || isBundleTarget || isCFBundleTarget)
1125       {
1126       typedef std::map<cmStdString, std::vector<cmSourceFile*> >
1127         mapOfVectorOfSourceFiles;
1128       mapOfVectorOfSourceFiles bundleFiles;
1129       for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
1130           i != classes.end(); ++i)
1131         {
1132         cmTarget::SourceFileFlags tsFlags =
1133           cmtarget.GetTargetSourceFileFlags(*i);
1134         if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
1135           {
1136           bundleFiles[tsFlags.MacFolder].push_back(*i);
1137           }
1138         }
1139       mapOfVectorOfSourceFiles::iterator mit;
1140       for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit )
1141         {
1142         cmXCodeObject* copyFilesBuildPhase =
1143           this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
1144         copyFilesBuildPhase->SetComment("Copy files");
1145         copyFilesBuildPhase->AddAttribute("buildActionMask",
1146           this->CreateString("2147483647"));
1147         copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
1148           this->CreateString("6"));
1149         cmOStringStream ostr;
1150         if (cmtarget.IsFrameworkOnApple())
1151           {
1152           // dstPath in frameworks is relative to Versions/<version>
1153           ostr << mit->first;
1154           }
1155         else if ( mit->first != "MacOS" )
1156           {
1157           // dstPath in bundles is relative to Contents/MacOS
1158           ostr << "../" << mit->first.c_str();
1159           }
1160         copyFilesBuildPhase->AddAttribute("dstPath",
1161           this->CreateString(ostr.str().c_str()));
1162         copyFilesBuildPhase->AddAttribute(
1163           "runOnlyForDeploymentPostprocessing", this->CreateString("0"));
1164         buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
1165         copyFilesBuildPhase->AddAttribute("files", buildFiles);
1166         std::vector<cmSourceFile*>::iterator sfIt;
1167         for ( sfIt = mit->second.begin(); sfIt != mit->second.end(); ++ sfIt )
1168           {
1169           cmXCodeObject* xsf =
1170             this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
1171                                         *sfIt, cmtarget);
1172           buildFiles->AddObject(xsf);
1173           }
1174         contentBuildPhases.push_back(copyFilesBuildPhase);
1175         }
1176       }
1177
1178     // create framework build phase
1179     cmXCodeObject* frameworkBuildPhase = 0;
1180     if (!externalObjFiles.empty())
1181       {
1182       frameworkBuildPhase =
1183         this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
1184       frameworkBuildPhase->SetComment("Frameworks");
1185       frameworkBuildPhase->AddAttribute("buildActionMask",
1186                                         this->CreateString("2147483647"));
1187       buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
1188       frameworkBuildPhase->AddAttribute("files", buildFiles);
1189       for(std::vector<cmXCodeObject*>::iterator i =  externalObjFiles.begin();
1190           i != externalObjFiles.end(); ++i)
1191         {
1192         buildFiles->AddObject(*i);
1193         }
1194       frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
1195                                         this->CreateString("0"));
1196       }
1197
1198     // create list of build phases and create the Xcode target
1199     cmXCodeObject* buildPhases =
1200       this->CreateObject(cmXCodeObject::OBJECT_LIST);
1201
1202     this->CreateCustomCommands(buildPhases, sourceBuildPhase,
1203                                headerBuildPhase, resourceBuildPhase,
1204                                contentBuildPhases,
1205                                frameworkBuildPhase, cmtarget);
1206
1207     targets.push_back(this->CreateXCodeTarget(cmtarget, buildPhases));
1208     }
1209 }
1210
1211 //----------------------------------------------------------------------------
1212 void cmGlobalXCodeGenerator::ForceLinkerLanguages()
1213 {
1214   // This makes sure all targets link using the proper language.
1215   for(std::map<cmStdString, cmTarget*>::const_iterator
1216         ti = this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
1217     {
1218     this->ForceLinkerLanguage(*ti->second);
1219     }
1220 }
1221
1222 //----------------------------------------------------------------------------
1223 void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
1224 {
1225   // This matters only for targets that link.
1226   if(cmtarget.GetType() != cmTarget::EXECUTABLE &&
1227      cmtarget.GetType() != cmTarget::SHARED_LIBRARY &&
1228      cmtarget.GetType() != cmTarget::MODULE_LIBRARY)
1229     {
1230     return;
1231     }
1232
1233   const char* llang = cmtarget.GetLinkerLanguage("NOCONFIG");
1234   if(!llang) { return; }
1235
1236   // If the language is compiled as a source trust Xcode to link with it.
1237   cmTarget::LinkImplementation const* impl =
1238     cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
1239   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
1240       li != impl->Languages.end(); ++li)
1241     {
1242     if(*li == llang) { return; }
1243     }
1244
1245   // Add an empty source file to the target that compiles with the
1246   // linker language.  This should convince Xcode to choose the proper
1247   // language.
1248   cmMakefile* mf = cmtarget.GetMakefile();
1249   std::string fname = mf->GetCurrentOutputDirectory();
1250   fname += cmake::GetCMakeFilesDirectory();
1251   fname += "/";
1252   fname += cmtarget.GetName();
1253   fname += "-CMakeForceLinker";
1254   fname += ".";
1255   fname += cmSystemTools::LowerCase(llang);
1256   {
1257   cmGeneratedFileStream fout(fname.c_str());
1258   fout << "\n";
1259   }
1260   if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
1261     {
1262     sf->SetProperty("LANGUAGE", llang);
1263     cmtarget.AddSourceFile(sf);
1264     }
1265 }
1266
1267 //----------------------------------------------------------------------------
1268 bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
1269 {
1270   const std::vector<std::string>& hdrExts =
1271     this->CurrentMakefile->GetHeaderExtensions();
1272   return (std::find(hdrExts.begin(), hdrExts.end(), sf->GetExtension()) !=
1273           hdrExts.end());
1274 }
1275
1276 //----------------------------------------------------------------------------
1277 cmXCodeObject*
1278 cmGlobalXCodeGenerator::CreateBuildPhase(const char* name,
1279                                          const char* name2,
1280                                          cmTarget& cmtarget,
1281                                          const std::vector<cmCustomCommand>&
1282                                          commands)
1283 {
1284   if(commands.size() == 0 && strcmp(name, "CMake ReRun") != 0)
1285     {
1286     return 0;
1287     }
1288   cmXCodeObject* buildPhase =
1289     this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
1290   buildPhase->AddAttribute("buildActionMask",
1291                            this->CreateString("2147483647"));
1292   cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
1293   buildPhase->AddAttribute("files", buildFiles);
1294   buildPhase->AddAttribute("name",
1295                            this->CreateString(name));
1296   buildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
1297                            this->CreateString("0"));
1298   buildPhase->AddAttribute("shellPath",
1299                            this->CreateString("/bin/sh"));
1300   this->AddCommandsToBuildPhase(buildPhase, cmtarget, commands,
1301                                 name2);
1302   return buildPhase;
1303 }
1304
1305 //----------------------------------------------------------------------------
1306 void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
1307                                                   cmXCodeObject*
1308                                                   sourceBuildPhase,
1309                                                   cmXCodeObject*
1310                                                   headerBuildPhase,
1311                                                   cmXCodeObject*
1312                                                   resourceBuildPhase,
1313                                                   std::vector<cmXCodeObject*>
1314                                                   contentBuildPhases,
1315                                                   cmXCodeObject*
1316                                                   frameworkBuildPhase,
1317                                                   cmTarget& cmtarget)
1318 {
1319   std::vector<cmCustomCommand> const & prebuild
1320     = cmtarget.GetPreBuildCommands();
1321   std::vector<cmCustomCommand> const & prelink
1322     = cmtarget.GetPreLinkCommands();
1323   std::vector<cmCustomCommand> postbuild
1324     = cmtarget.GetPostBuildCommands();
1325
1326   if(cmtarget.GetType() == cmTarget::SHARED_LIBRARY &&
1327     !cmtarget.IsFrameworkOnApple())
1328     {
1329     cmCustomCommandLines cmd;
1330     cmd.resize(1);
1331     cmd[0].push_back(this->CurrentMakefile->GetDefinition("CMAKE_COMMAND"));
1332     cmd[0].push_back("-E");
1333     cmd[0].push_back("cmake_symlink_library");
1334     std::string str_file = "$<TARGET_FILE:";
1335     str_file += cmtarget.GetName();
1336     str_file += ">";
1337     std::string str_so_file = "$<TARGET_SONAME_FILE:";
1338     str_so_file += cmtarget.GetName();
1339     str_so_file += ">";
1340     std::string str_link_file = "$<TARGET_LINKER_FILE:";
1341     str_link_file += cmtarget.GetName();
1342     str_link_file += ">";
1343     cmd[0].push_back(str_file);
1344     cmd[0].push_back(str_so_file);
1345     cmd[0].push_back(str_link_file);
1346
1347     cmCustomCommand command(this->CurrentMakefile,
1348       std::vector<std::string>(),
1349       std::vector<std::string>(),
1350       cmd,
1351       "Creating symlinks",
1352       "");
1353
1354     postbuild.push_back(command);
1355     }
1356
1357   std::vector<cmSourceFile*>const &classes = cmtarget.GetSourceFiles();
1358   // add all the sources
1359   std::vector<cmCustomCommand> commands;
1360   for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
1361       i != classes.end(); ++i)
1362     {
1363     if((*i)->GetCustomCommand())
1364       {
1365       commands.push_back(*(*i)->GetCustomCommand());
1366       }
1367     }
1368   // create prebuild phase
1369   cmXCodeObject* cmakeRulesBuildPhase =
1370     this->CreateBuildPhase("CMake Rules",
1371                            "cmakeRulesBuildPhase",
1372                            cmtarget, commands);
1373   // create prebuild phase
1374   cmXCodeObject* preBuildPhase =
1375     this->CreateBuildPhase("CMake PreBuild Rules", "preBuildCommands",
1376                            cmtarget, prebuild);
1377   // create prelink phase
1378   cmXCodeObject* preLinkPhase =
1379     this->CreateBuildPhase("CMake PreLink Rules", "preLinkCommands",
1380                            cmtarget, prelink);
1381   // create postbuild phase
1382   cmXCodeObject* postBuildPhase =
1383     this->CreateBuildPhase("CMake PostBuild Rules", "postBuildPhase",
1384                            cmtarget, postbuild);
1385
1386   // The order here is the order they will be built in.
1387   // The order "headers, resources, sources" mimics a native project generated
1388   // from an xcode template...
1389   //
1390   if(preBuildPhase)
1391     {
1392     buildPhases->AddObject(preBuildPhase);
1393     }
1394   if(cmakeRulesBuildPhase)
1395     {
1396     buildPhases->AddObject(cmakeRulesBuildPhase);
1397     }
1398   if(headerBuildPhase)
1399     {
1400     buildPhases->AddObject(headerBuildPhase);
1401     }
1402   if(resourceBuildPhase)
1403     {
1404     buildPhases->AddObject(resourceBuildPhase);
1405     }
1406   std::vector<cmXCodeObject*>::iterator cit;
1407   for (cit = contentBuildPhases.begin(); cit != contentBuildPhases.end();
1408        ++cit)
1409     {
1410     buildPhases->AddObject(*cit);
1411     }
1412   if(sourceBuildPhase)
1413     {
1414     buildPhases->AddObject(sourceBuildPhase);
1415     }
1416   if(preLinkPhase)
1417     {
1418     buildPhases->AddObject(preLinkPhase);
1419     }
1420   if(frameworkBuildPhase)
1421     {
1422     buildPhases->AddObject(frameworkBuildPhase);
1423     }
1424   if(postBuildPhase)
1425     {
1426     buildPhases->AddObject(postBuildPhase);
1427     }
1428 }
1429
1430 //----------------------------------------------------------------------------
1431 // This function removes each occurrence of the flag and returns the last one
1432 // (i.e., the dominant flag in GCC)
1433 std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
1434                                                 std::string& flags)
1435 {
1436   std::string retFlag;
1437   std::string::size_type lastOccurancePos = flags.rfind(flag);
1438   bool saved = false;
1439   while(lastOccurancePos != flags.npos)
1440     {
1441     //increment pos, we use lastOccurancePos to reduce search space on next inc
1442     std::string::size_type pos = lastOccurancePos;
1443     if(pos == 0 || flags[pos-1]==' ')
1444       {
1445       while(pos < flags.size() && flags[pos] != ' ')
1446         {
1447         if(!saved)
1448           {
1449           retFlag += flags[pos];
1450           }
1451         flags[pos] = ' ';
1452         pos++;
1453         }
1454       saved = true;
1455       }
1456     //decrement lastOccurancePos while making sure we don't loop around
1457     //and become a very large positive number since size_type is unsigned
1458     lastOccurancePos = lastOccurancePos == 0 ? 0 : lastOccurancePos-1;
1459     lastOccurancePos = flags.rfind(flag,lastOccurancePos);
1460     }
1461   return retFlag;
1462 }
1463
1464 //----------------------------------------------------------------------------
1465 void
1466 cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
1467                                                 cmTarget& target,
1468                                                 std::vector<cmCustomCommand>
1469                                                 const & commands,
1470                                                 const char* name)
1471 {
1472
1473   // collect multiple outputs of custom commands into a set
1474   // which will be used for every configuration
1475   std::map<cmStdString, cmStdString> multipleOutputPairs;
1476   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
1477       i != commands.end(); ++i)
1478     {
1479     cmCustomCommand const& cc = *i;
1480     if(!cc.GetCommandLines().empty())
1481       {
1482       const std::vector<std::string>& outputs = cc.GetOutputs();
1483       if(!outputs.empty())
1484         {
1485         // If there are more than one outputs treat the
1486         // first as the primary output and make the rest depend on it.
1487         std::vector<std::string>::const_iterator o = outputs.begin();
1488         std::string primaryOutput = this->ConvertToRelativeForMake(o->c_str());
1489         for(++o; o != outputs.end(); ++o)
1490           {
1491           std::string currentOutput=this->ConvertToRelativeForMake(o->c_str());
1492           multipleOutputPairs[currentOutput] = primaryOutput;
1493           }
1494         }
1495       }
1496     }
1497
1498   std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
1499   dir += "/CMakeScripts";
1500   cmSystemTools::MakeDirectory(dir.c_str());
1501   std::string makefile = dir;
1502   makefile += "/";
1503   makefile += target.GetName();
1504   makefile += "_";
1505   makefile += name;
1506   makefile += ".make";
1507
1508   for (std::vector<std::string>::const_iterator currentConfig=
1509             this->CurrentConfigurationTypes.begin();
1510        currentConfig!=this->CurrentConfigurationTypes.end();
1511        currentConfig++ )
1512     {
1513     this->CreateCustomRulesMakefile(makefile.c_str(),
1514                                     target,
1515                                     commands,
1516                                     currentConfig->c_str(),
1517                                     multipleOutputPairs);
1518     }
1519
1520   std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory();
1521   cdir = this->ConvertToRelativeForXCode(cdir.c_str());
1522   std::string makecmd = "make -C ";
1523   makecmd += cdir;
1524   makecmd += " -f ";
1525   makecmd += this->ConvertToRelativeForMake(
1526                                           (makefile+"$CONFIGURATION").c_str());
1527   if(!multipleOutputPairs.empty())
1528     {
1529     makecmd += " cmake_check_multiple_outputs";
1530     }
1531   makecmd += " all";
1532   cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
1533   buildphase->AddAttribute("shellScript",
1534                            this->CreateString(makecmd.c_str()));
1535   buildphase->AddAttribute("showEnvVarsInLog",
1536                            this->CreateString("0"));
1537 }
1538
1539 //----------------------------------------------------------------------------
1540 void  cmGlobalXCodeGenerator
1541 ::CreateCustomRulesMakefile(const char* makefileBasename,
1542                             cmTarget& target,
1543                             std::vector<cmCustomCommand>
1544                             const & commands,
1545                             const char* configName,
1546                             const std::map<cmStdString,
1547                             cmStdString>& multipleOutputPairs
1548                            )
1549 {
1550   std::string makefileName=makefileBasename;
1551   if(this->XcodeVersion > 20)
1552     {
1553     makefileName+=configName;
1554     }
1555   cmGeneratedFileStream makefileStream(makefileName.c_str());
1556   if(!makefileStream)
1557     {
1558     return;
1559     }
1560   makefileStream.SetCopyIfDifferent(true);
1561   makefileStream << "# Generated by CMake, DO NOT EDIT\n";
1562   makefileStream << "# Custom rules for " << target.GetName() << "\n";
1563
1564   // disable the implicit rules
1565   makefileStream << ".SUFFIXES: " << "\n";
1566
1567   // have all depend on all outputs
1568   makefileStream << "all: ";
1569   std::map<const cmCustomCommand*, cmStdString> tname;
1570   int count = 0;
1571   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
1572       i != commands.end(); ++i)
1573     {
1574     cmCustomCommand const& cc = *i;
1575     if(!cc.GetCommandLines().empty())
1576       {
1577       const std::vector<std::string>& outputs = cc.GetOutputs();
1578       if(!outputs.empty())
1579         {
1580         for(std::vector<std::string>::const_iterator o = outputs.begin();
1581             o != outputs.end(); ++o)
1582           {
1583           makefileStream
1584               << "\\\n\t" << this->ConvertToRelativeForMake(o->c_str());
1585           }
1586         }
1587       else
1588         {
1589         cmOStringStream str;
1590         str << "_buildpart_" << count++ ;
1591         tname[&cc] = std::string(target.GetName()) + str.str();
1592         makefileStream << "\\\n\t" << tname[&cc];
1593         }
1594       }
1595     }
1596   makefileStream << "\n\n";
1597   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
1598       i != commands.end(); ++i)
1599     {
1600     cmCustomCommand const& cc = *i;
1601     if(!cc.GetCommandLines().empty())
1602       {
1603       cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
1604       makefileStream << "\n";
1605       const std::vector<std::string>& outputs = cc.GetOutputs();
1606       if(!outputs.empty())
1607         {
1608         // There is at least one output, start the rule for it
1609         std::string primary_output =
1610             this->ConvertToRelativeForMake(outputs.begin()->c_str());
1611         makefileStream << primary_output << ": ";
1612         }
1613       else
1614         {
1615         // There are no outputs.  Use the generated force rule name.
1616         makefileStream << tname[&cc] << ": ";
1617         }
1618       for(std::vector<std::string>::const_iterator d =
1619           cc.GetDepends().begin();
1620           d != cc.GetDepends().end(); ++d)
1621         {
1622         std::string dep;
1623         if(this->CurrentLocalGenerator
1624            ->GetRealDependency(d->c_str(), configName, dep))
1625           {
1626           makefileStream << "\\\n" <<
1627             this->ConvertToRelativeForMake(dep.c_str());
1628           }
1629         }
1630       makefileStream << "\n";
1631
1632       if(const char* comment = cc.GetComment())
1633         {
1634         std::string echo_cmd = "echo ";
1635         echo_cmd += (this->CurrentLocalGenerator->
1636                      EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
1637         makefileStream << "\t" << echo_cmd.c_str() << "\n";
1638         }
1639
1640       // Add each command line to the set of commands.
1641       for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
1642         {
1643         // Build the command line in a single string.
1644         std::string cmd2 = ccg.GetCommand(c);
1645         cmSystemTools::ReplaceString(cmd2, "/./", "/");
1646         cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
1647         std::string cmd;
1648         if(cc.GetWorkingDirectory())
1649           {
1650           cmd += "cd ";
1651           cmd += this->ConvertToRelativeForMake(cc.GetWorkingDirectory());
1652           cmd += " && ";
1653           }
1654         cmd += cmd2;
1655         ccg.AppendArguments(c, cmd);
1656         makefileStream << "\t" << cmd.c_str() << "\n";
1657         }
1658       }
1659     }
1660
1661   // Add rules to deal with multiple outputs of custom commands.
1662   if(!multipleOutputPairs.empty())
1663     {
1664     makefileStream <<
1665         "\n# Dependencies of multiple outputs to their primary outputs \n";
1666
1667     for(std::map<cmStdString, cmStdString>::const_iterator o =
1668         multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
1669       {
1670       makefileStream << o->first << ": " << o->second << "\n";
1671       }
1672
1673     makefileStream <<
1674         "\n"
1675         "cmake_check_multiple_outputs:\n";
1676     for(std::map<cmStdString, cmStdString>::const_iterator o =
1677         multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
1678       {
1679       makefileStream << "\t@if [ ! -f "
1680           << o->first << " ]; then rm -f "
1681           << o->second << "; fi\n";
1682       }
1683     }
1684 }
1685
1686 //----------------------------------------------------------------------------
1687 void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
1688                                                  cmXCodeObject* buildSettings,
1689                                                  const char* configName)
1690 {
1691   std::string flags;
1692   std::string defFlags;
1693   bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
1694                  (target.GetType() == cmTarget::MODULE_LIBRARY));
1695   bool binary = ((target.GetType() == cmTarget::OBJECT_LIBRARY) ||
1696                  (target.GetType() == cmTarget::STATIC_LIBRARY) ||
1697                  (target.GetType() == cmTarget::EXECUTABLE) ||
1698                  shared);
1699
1700   const char* lang = target.GetLinkerLanguage(configName);
1701   std::string cflags;
1702   if(lang)
1703     {
1704     // for c++ projects get the c flags as well
1705     if(strcmp(lang, "CXX") == 0)
1706       {
1707       this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
1708       this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target,
1709                                                    "C", configName);
1710       this->CurrentLocalGenerator->
1711         AddCompileOptions(cflags, &target, "C", configName);
1712       }
1713
1714     // Add language-specific flags.
1715     this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
1716
1717     // Add shared-library flags if needed.
1718     this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target,
1719                                                  lang, configName);
1720
1721     this->CurrentLocalGenerator->AddVisibilityPresetFlags(flags, &target,
1722                                                    lang);
1723
1724     this->CurrentLocalGenerator->
1725       AddCompileOptions(flags, &target, lang, configName);
1726     }
1727   else if(binary)
1728   {
1729     cmSystemTools::Error
1730       ("CMake can not determine linker language for target: ",
1731        target.GetName());
1732     return;
1733   }
1734
1735   // Add define flags
1736   this->CurrentLocalGenerator->
1737     AppendFlags(defFlags,
1738                 this->CurrentMakefile->GetDefineFlags());
1739
1740   // Add preprocessor definitions for this target and configuration.
1741   BuildObjectListOrString ppDefs(this, this->XcodeVersion >= 30);
1742   if(this->XcodeVersion > 15)
1743     {
1744     this->AppendDefines(ppDefs,
1745       "CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"");
1746     }
1747   if(const char* exportMacro = target.GetExportMacro())
1748     {
1749     // Add the export symbol definition for shared library objects.
1750     this->AppendDefines(ppDefs, exportMacro);
1751     }
1752   cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
1753   std::vector<std::string> targetDefines;
1754   target.GetCompileDefinitions(targetDefines, configName);
1755   this->AppendDefines(ppDefs, targetDefines);
1756   buildSettings->AddAttribute
1757     ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
1758
1759   std::string extraLinkOptionsVar;
1760   std::string extraLinkOptions;
1761   if(target.GetType() == cmTarget::EXECUTABLE)
1762     {
1763     extraLinkOptionsVar = "CMAKE_EXE_LINKER_FLAGS";
1764     }
1765   else if(target.GetType() == cmTarget::SHARED_LIBRARY)
1766     {
1767     extraLinkOptionsVar = "CMAKE_SHARED_LINKER_FLAGS";
1768     }
1769   else if(target.GetType() == cmTarget::MODULE_LIBRARY)
1770     {
1771     extraLinkOptionsVar = "CMAKE_MODULE_LINKER_FLAGS";
1772     }
1773   if(extraLinkOptionsVar.size())
1774     {
1775     this->CurrentLocalGenerator
1776       ->AddConfigVariableFlags(extraLinkOptions,
1777                                extraLinkOptionsVar.c_str(),
1778                                configName);
1779     }
1780
1781   if(target.GetType() == cmTarget::OBJECT_LIBRARY ||
1782      target.GetType() == cmTarget::STATIC_LIBRARY)
1783     {
1784     this->CurrentLocalGenerator
1785       ->GetStaticLibraryFlags(extraLinkOptions,
1786                               cmSystemTools::UpperCase(configName),
1787                               &target);
1788     }
1789   else
1790     {
1791     const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
1792     if(targetLinkFlags)
1793       {
1794       this->CurrentLocalGenerator->
1795         AppendFlags(extraLinkOptions, targetLinkFlags);
1796       }
1797     if(configName && *configName)
1798       {
1799       std::string linkFlagsVar = "LINK_FLAGS_";
1800       linkFlagsVar += cmSystemTools::UpperCase(configName);
1801       if(const char* linkFlags = target.GetProperty(linkFlagsVar.c_str()))
1802         {
1803         this->CurrentLocalGenerator->
1804           AppendFlags(extraLinkOptions, linkFlags);
1805         }
1806       }
1807     }
1808
1809   // Set target-specific architectures.
1810   std::vector<std::string> archs;
1811   gtgt->GetAppleArchs(configName, archs);
1812
1813   if(!archs.empty())
1814     {
1815     // Enable ARCHS attribute.
1816     buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
1817                                 this->CreateString("NO"));
1818
1819     // Store ARCHS value.
1820     if(archs.size() == 1)
1821       {
1822       buildSettings->AddAttribute("ARCHS",
1823                                   this->CreateString(archs[0].c_str()));
1824       }
1825     else
1826       {
1827       cmXCodeObject* archObjects =
1828         this->CreateObject(cmXCodeObject::OBJECT_LIST);
1829       for(std::vector<std::string>::iterator i = archs.begin();
1830           i != archs.end(); i++)
1831         {
1832         archObjects->AddObject(this->CreateString((*i).c_str()));
1833         }
1834       buildSettings->AddAttribute("ARCHS", archObjects);
1835       }
1836     }
1837
1838   // Get the product name components.
1839   std::string pnprefix;
1840   std::string pnbase;
1841   std::string pnsuffix;
1842   target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
1843
1844   const char* version = target.GetProperty("VERSION");
1845   const char* soversion = target.GetProperty("SOVERSION");
1846   if(!target.HasSOName(configName) || target.IsFrameworkOnApple())
1847     {
1848     version = 0;
1849     soversion = 0;
1850     }
1851   if(version && !soversion)
1852     {
1853     soversion = version;
1854     }
1855   if(!version && soversion)
1856     {
1857     version = soversion;
1858     }
1859
1860   std::string realName = pnbase;
1861   std::string soName = pnbase;
1862   if(version && soversion)
1863     {
1864     realName += ".";
1865     realName += version;
1866     soName += ".";
1867     soName += soversion;
1868     }
1869
1870   // Set attributes to specify the proper name for the target.
1871   std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory();
1872   if(target.GetType() == cmTarget::STATIC_LIBRARY ||
1873      target.GetType() == cmTarget::SHARED_LIBRARY ||
1874      target.GetType() == cmTarget::MODULE_LIBRARY ||
1875      target.GetType() == cmTarget::EXECUTABLE)
1876     {
1877     if(this->XcodeVersion >= 21)
1878       {
1879       if(!target.UsesDefaultOutputDir(configName, false))
1880         {
1881         std::string pncdir = target.GetDirectory(configName);
1882         buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
1883                                     this->CreateString(pncdir.c_str()));
1884         }
1885       }
1886     else
1887       {
1888       buildSettings->AddAttribute("OBJROOT",
1889                                   this->CreateString(pndir.c_str()));
1890       pndir = target.GetDirectory(configName);
1891       }
1892
1893     if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple())
1894       {
1895       pnprefix = "";
1896       }
1897
1898     buildSettings->AddAttribute("EXECUTABLE_PREFIX",
1899                                 this->CreateString(pnprefix.c_str()));
1900     buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
1901                                 this->CreateString(pnsuffix.c_str()));
1902     }
1903   else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
1904     {
1905     pnprefix = "lib";
1906     pnbase = target.GetName();
1907     pnsuffix = ".a";
1908
1909     if(this->XcodeVersion >= 21)
1910       {
1911       std::string pncdir = this->GetObjectsNormalDirectory(
1912         this->CurrentProject, configName, &target);
1913       buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
1914                                   this->CreateString(pncdir.c_str()));
1915       }
1916     else
1917       {
1918       buildSettings->AddAttribute("OBJROOT",
1919                                   this->CreateString(pndir.c_str()));
1920       pndir = this->GetObjectsNormalDirectory(
1921         this->CurrentProject, configName, &target);
1922       }
1923     }
1924
1925   // Store the product name for all target types.
1926   buildSettings->AddAttribute("PRODUCT_NAME",
1927                               this->CreateString(realName.c_str()));
1928   buildSettings->AddAttribute("SYMROOT",
1929                               this->CreateString(pndir.c_str()));
1930
1931   // Handle settings for each target type.
1932   switch(target.GetType())
1933     {
1934     case cmTarget::OBJECT_LIBRARY:
1935     case cmTarget::STATIC_LIBRARY:
1936     {
1937     buildSettings->AddAttribute("LIBRARY_STYLE",
1938                                 this->CreateString("STATIC"));
1939     break;
1940     }
1941
1942     case cmTarget::MODULE_LIBRARY:
1943     {
1944     buildSettings->AddAttribute("LIBRARY_STYLE",
1945                                 this->CreateString("BUNDLE"));
1946     if (target.GetPropertyAsBool("BUNDLE"))
1947       {
1948       // It turns out that a BUNDLE is basically the same
1949       // in many ways as an application bundle, as far as
1950       // link flags go
1951       std::string createFlags =
1952         this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
1953                           "-bundle");
1954       if(!createFlags.empty())
1955         {
1956         extraLinkOptions += " ";
1957         extraLinkOptions += createFlags;
1958         }
1959       std::string plist = this->ComputeInfoPListLocation(target);
1960       // Xcode will create the final version of Info.plist at build time,
1961       // so let it replace the cfbundle name. This avoids creating
1962       // a per-configuration Info.plist file. The cfbundle plist
1963       // is very similar to the application bundle plist
1964       this->CurrentLocalGenerator
1965         ->GenerateAppleInfoPList(&target, "$(EXECUTABLE_NAME)",
1966                                  plist.c_str());
1967       std::string path =
1968         this->ConvertToRelativeForXCode(plist.c_str());
1969       buildSettings->AddAttribute("INFOPLIST_FILE",
1970                                   this->CreateString(path.c_str()));
1971       }
1972     else if(this->XcodeVersion >= 22)
1973       {
1974       buildSettings->AddAttribute("MACH_O_TYPE",
1975                                   this->CreateString("mh_bundle"));
1976       buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC",
1977                                   this->CreateString("NO"));
1978       // Add the flags to create an executable.
1979       std::string createFlags =
1980         this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
1981       if(!createFlags.empty())
1982         {
1983         extraLinkOptions += " ";
1984         extraLinkOptions += createFlags;
1985         }
1986       }
1987     else
1988       {
1989       // Add the flags to create a module.
1990       std::string createFlags =
1991         this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
1992                           "-bundle");
1993       if(!createFlags.empty())
1994         {
1995         extraLinkOptions += " ";
1996         extraLinkOptions += createFlags;
1997         }
1998       }
1999     break;
2000     }
2001     case cmTarget::SHARED_LIBRARY:
2002     {
2003     if(target.GetPropertyAsBool("FRAMEWORK"))
2004       {
2005       std::string fw_version = target.GetFrameworkVersion();
2006       buildSettings->AddAttribute("FRAMEWORK_VERSION",
2007                                   this->CreateString(fw_version.c_str()));
2008
2009       std::string plist = this->ComputeInfoPListLocation(target);
2010       // Xcode will create the final version of Info.plist at build time,
2011       // so let it replace the framework name. This avoids creating
2012       // a per-configuration Info.plist file.
2013       this->CurrentLocalGenerator
2014         ->GenerateFrameworkInfoPList(&target, "$(EXECUTABLE_NAME)",
2015                                      plist.c_str());
2016       std::string path =
2017         this->ConvertToRelativeForXCode(plist.c_str());
2018       buildSettings->AddAttribute("INFOPLIST_FILE",
2019                                   this->CreateString(path.c_str()));
2020       }
2021     else
2022       {
2023       // Add the flags to create a shared library.
2024       std::string createFlags =
2025         this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS",
2026                           "-dynamiclib");
2027       if(!createFlags.empty())
2028         {
2029         extraLinkOptions += " ";
2030         extraLinkOptions += createFlags;
2031         }
2032       }
2033
2034     buildSettings->AddAttribute("LIBRARY_STYLE",
2035                                 this->CreateString("DYNAMIC"));
2036     break;
2037     }
2038     case cmTarget::EXECUTABLE:
2039     {
2040     // Add the flags to create an executable.
2041     std::string createFlags =
2042       this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
2043     if(!createFlags.empty())
2044       {
2045       extraLinkOptions += " ";
2046       extraLinkOptions += createFlags;
2047       }
2048
2049     // Handle bundles and normal executables separately.
2050     if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
2051       {
2052       std::string plist = this->ComputeInfoPListLocation(target);
2053       // Xcode will create the final version of Info.plist at build time,
2054       // so let it replace the executable name.  This avoids creating
2055       // a per-configuration Info.plist file.
2056       this->CurrentLocalGenerator
2057         ->GenerateAppleInfoPList(&target, "$(EXECUTABLE_NAME)",
2058                                  plist.c_str());
2059       std::string path =
2060         this->ConvertToRelativeForXCode(plist.c_str());
2061       buildSettings->AddAttribute("INFOPLIST_FILE",
2062                                   this->CreateString(path.c_str()));
2063
2064       }
2065     }
2066     break;
2067     default:
2068       break;
2069     }
2070   if(this->XcodeVersion >= 22 && this->XcodeVersion < 40)
2071     {
2072     buildSettings->AddAttribute("PREBINDING",
2073                                 this->CreateString("NO"));
2074     }
2075
2076   BuildObjectListOrString dirs(this, this->XcodeVersion >= 30);
2077   BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30);
2078   std::vector<std::string> includes;
2079   this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt,
2080                                                      "C", configName);
2081   std::set<cmStdString> emitted;
2082   emitted.insert("/System/Library/Frameworks");
2083   for(std::vector<std::string>::iterator i = includes.begin();
2084       i != includes.end(); ++i)
2085     {
2086     if(this->NameResolvesToFramework(i->c_str()))
2087       {
2088       std::string frameworkDir = *i;
2089       frameworkDir += "/../";
2090       frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
2091       if(emitted.insert(frameworkDir).second)
2092         {
2093         fdirs.Add(this->XCodeEscapePath(frameworkDir.c_str()).c_str());
2094         }
2095       }
2096     else
2097       {
2098       std::string incpath =
2099         this->XCodeEscapePath(i->c_str());
2100       dirs.Add(incpath.c_str());
2101       }
2102     }
2103   // Add framework search paths needed for linking.
2104   if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName))
2105     {
2106     std::vector<std::string> const& fwDirs = cli->GetFrameworkPaths();
2107     for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
2108         fdi != fwDirs.end(); ++fdi)
2109       {
2110       if(emitted.insert(*fdi).second)
2111         {
2112         fdirs.Add(this->XCodeEscapePath(fdi->c_str()).c_str());
2113         }
2114       }
2115     }
2116   if(!fdirs.IsEmpty())
2117     {
2118     buildSettings->AddAttribute("FRAMEWORK_SEARCH_PATHS",
2119                                 fdirs.CreateList());
2120     }
2121   if(!dirs.IsEmpty())
2122     {
2123     buildSettings->AddAttribute("HEADER_SEARCH_PATHS",
2124                                 dirs.CreateList());
2125     }
2126   std::string oflagc = this->ExtractFlag("-O", cflags);
2127   char optLevel[2];
2128   optLevel[0] = '0';
2129   optLevel[1] = 0;
2130   if(oflagc.size() == 3)
2131     {
2132     optLevel[0] = oflagc[2];
2133     }
2134   if(oflagc.size() == 2)
2135     {
2136     optLevel[0] = '1';
2137     }
2138   std::string oflag = this->ExtractFlag("-O", flags);
2139   if(oflag.size() == 3)
2140     {
2141     optLevel[0] = oflag[2];
2142     }
2143   if(oflag.size() == 2)
2144     {
2145     optLevel[0] = '1';
2146     }
2147   std::string gflagc = this->ExtractFlag("-g", cflags);
2148   // put back gdwarf-2 if used since there is no way
2149   // to represent it in the gui, but we still want debug yes
2150   if(gflagc == "-gdwarf-2")
2151     {
2152     cflags += " ";
2153     cflags += gflagc;
2154     }
2155   std::string gflag = this->ExtractFlag("-g", flags);
2156   if(gflag == "-gdwarf-2")
2157     {
2158     flags += " ";
2159     flags += gflag;
2160     }
2161   const char* debugStr = "YES";
2162   // We can't set the Xcode flag differently depending on the language,
2163   // so put them back in this case.
2164   if( (lang && strcmp(lang, "CXX") == 0) && gflag != gflagc )
2165     {
2166     cflags += " ";
2167     cflags += gflagc;
2168     flags += " ";
2169     flags += gflag;
2170     debugStr = "NO";
2171     }
2172   if( gflag == "-g0" || gflag.size() == 0 )
2173     {
2174     debugStr = "NO";
2175     }
2176
2177   buildSettings->AddAttribute("COMBINE_HIDPI_IMAGES",
2178                               this->CreateString("YES"));
2179   buildSettings->AddAttribute("GCC_GENERATE_DEBUGGING_SYMBOLS",
2180                               this->CreateString(debugStr));
2181   buildSettings->AddAttribute("GCC_OPTIMIZATION_LEVEL",
2182                               this->CreateString(optLevel));
2183   buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN",
2184                               this->CreateString("NO"));
2185   buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN",
2186                               this->CreateString("NO"));
2187   if(lang && strcmp(lang, "CXX") == 0)
2188     {
2189     flags += " ";
2190     flags += defFlags;
2191     buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
2192                                 this->CreateString(flags.c_str()));
2193     cflags += " ";
2194     cflags += defFlags;
2195     buildSettings->AddAttribute("OTHER_CFLAGS",
2196                                 this->CreateString(cflags.c_str()));
2197
2198     }
2199   else
2200     {
2201     flags += " ";
2202     flags += defFlags;
2203     buildSettings->AddAttribute("OTHER_CFLAGS",
2204                                 this->CreateString(flags.c_str()));
2205     }
2206
2207   // Add Fortran source format attribute if property is set.
2208   const char* format = 0;
2209   const char* tgtfmt = target.GetProperty("Fortran_FORMAT");
2210   switch(this->CurrentLocalGenerator->GetFortranFormat(tgtfmt))
2211     {
2212     case cmLocalGenerator::FortranFormatFixed: format = "fixed"; break;
2213     case cmLocalGenerator::FortranFormatFree: format = "free"; break;
2214     default: break;
2215     }
2216   if(format)
2217     {
2218     buildSettings->AddAttribute("IFORT_LANG_SRCFMT",
2219                                 this->CreateString(format));
2220     }
2221
2222   // Create the INSTALL_PATH attribute.
2223   std::string install_name_dir;
2224   if(target.GetType() == cmTarget::SHARED_LIBRARY)
2225     {
2226     // Get the install_name directory for the build tree.
2227     install_name_dir = target.GetInstallNameDirForBuildTree(configName);
2228     // Xcode doesn't create the correct install_name in some cases.
2229     // That is, if the INSTALL_PATH is empty, or if we have versioning
2230     // of dylib libraries, we want to specify the install_name.
2231     // This is done by adding a link flag to create an install_name
2232     // with just the library soname.
2233     std::string install_name;
2234     if(!install_name_dir.empty())
2235       {
2236       // Convert to a path for the native build tool.
2237       cmSystemTools::ConvertToUnixSlashes(install_name_dir);
2238       install_name += install_name_dir;
2239       install_name += "/";
2240       }
2241     install_name += target.GetSOName(configName);
2242
2243     if((realName != soName) || install_name_dir.empty())
2244       {
2245       install_name_dir = "";
2246       extraLinkOptions += " -install_name ";
2247       extraLinkOptions += XCodeEscapePath(install_name.c_str());
2248       }
2249     }
2250   buildSettings->AddAttribute("INSTALL_PATH",
2251                               this->CreateString(install_name_dir.c_str()));
2252
2253   // Create the LD_RUNPATH_SEARCH_PATHS
2254   cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
2255   if(pcli)
2256     {
2257     std::string search_paths;
2258     std::vector<std::string> runtimeDirs;
2259     pcli->GetRPath(runtimeDirs, false);
2260     for(std::vector<std::string>::const_iterator i = runtimeDirs.begin();
2261         i != runtimeDirs.end(); ++i)
2262       {
2263       if(!search_paths.empty())
2264         {
2265         search_paths += " ";
2266         }
2267       search_paths += this->XCodeEscapePath((*i).c_str());
2268       }
2269     if(!search_paths.empty())
2270       {
2271       buildSettings->AddAttribute("LD_RUNPATH_SEARCH_PATHS",
2272                                   this->CreateString(search_paths.c_str()));
2273       }
2274     }
2275
2276   buildSettings->AddAttribute("OTHER_LDFLAGS",
2277                               this->CreateString(extraLinkOptions.c_str()));
2278   buildSettings->AddAttribute("OTHER_REZFLAGS",
2279                               this->CreateString(""));
2280   buildSettings->AddAttribute("SECTORDER_FLAGS",
2281                               this->CreateString(""));
2282   buildSettings->AddAttribute("USE_HEADERMAP",
2283                               this->CreateString("NO"));
2284   if (this->XcodeVersion >= 30)
2285     {
2286     cmXCodeObject *group = this->CreateObject(cmXCodeObject::OBJECT_LIST);
2287     group->AddObject(this->CreateString("-Wmost"));
2288     group->AddObject(this->CreateString("-Wno-four-char-constants"));
2289     group->AddObject(this->CreateString("-Wno-unknown-pragmas"));
2290     buildSettings->AddAttribute("WARNING_CFLAGS", group);
2291     }
2292   else
2293     {
2294     buildSettings->AddAttribute("WARNING_CFLAGS",
2295                                 this->CreateString(
2296                                   "-Wmost -Wno-four-char-constants"
2297                                   " -Wno-unknown-pragmas"));
2298     }
2299
2300   // Runtime version information.
2301   if(target.GetType() == cmTarget::SHARED_LIBRARY)
2302     {
2303     int major;
2304     int minor;
2305     int patch;
2306
2307     // VERSION -> current_version
2308     target.GetTargetVersion(false, major, minor, patch);
2309     cmOStringStream v;
2310
2311     // Xcode always wants at least 1.0.0 or nothing
2312     if(!(major == 0 && minor == 0 && patch == 0))
2313       {
2314       v << major << "." << minor << "." << patch;
2315       }
2316     buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
2317                                 this->CreateString(v.str().c_str()));
2318
2319     // SOVERSION -> compatibility_version
2320     target.GetTargetVersion(true, major, minor, patch);
2321     cmOStringStream vso;
2322
2323     // Xcode always wants at least 1.0.0 or nothing
2324     if(!(major == 0 && minor == 0 && patch == 0))
2325       {
2326       vso << major << "." << minor << "." << patch;
2327       }
2328     buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
2329                                 this->CreateString(vso.str().c_str()));
2330     }
2331   // put this last so it can override existing settings
2332   // Convert "XCODE_ATTRIBUTE_*" properties directly.
2333   {
2334   cmPropertyMap const& props = target.GetProperties();
2335   for(cmPropertyMap::const_iterator i = props.begin();
2336       i != props.end(); ++i)
2337     {
2338     if(i->first.find("XCODE_ATTRIBUTE_") == 0)
2339       {
2340       cmStdString attribute = i->first.substr(16);
2341       // Handle [variant=<config>] condition explicitly here.
2342       cmStdString::size_type beginVariant =
2343         attribute.find("[variant=");
2344       if (beginVariant != cmStdString::npos)
2345         {
2346         cmStdString::size_type endVariant =
2347           attribute.find("]", beginVariant+9);
2348         if (endVariant != cmStdString::npos)
2349           {
2350           // Compare the variant to the configuration.
2351           cmStdString variant =
2352             attribute.substr(beginVariant+9, endVariant-beginVariant-9);
2353           if (variant == configName)
2354             {
2355             // The variant matches the configuration so use this
2356             // attribute but drop the [variant=<config>] condition.
2357             attribute.erase(beginVariant, endVariant-beginVariant+1);
2358             }
2359           else
2360             {
2361             // The variant does not match the configuration so
2362             // do not use this attribute.
2363             attribute.clear();
2364             }
2365           }
2366         }
2367
2368       if (!attribute.empty())
2369         {
2370         buildSettings->AddAttribute(attribute.c_str(),
2371                                     this->CreateString(i->second.GetValue()));
2372         }
2373       }
2374     }
2375   }
2376 }
2377
2378 //----------------------------------------------------------------------------
2379 cmXCodeObject*
2380 cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
2381 {
2382   cmXCodeObject* shellBuildPhase =
2383     this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
2384   shellBuildPhase->AddAttribute("buildActionMask",
2385                                 this->CreateString("2147483647"));
2386   cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
2387   shellBuildPhase->AddAttribute("files", buildFiles);
2388   cmXCodeObject* inputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
2389   shellBuildPhase->AddAttribute("inputPaths", inputPaths);
2390   cmXCodeObject* outputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
2391   shellBuildPhase->AddAttribute("outputPaths", outputPaths);
2392   shellBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
2393                                 this->CreateString("0"));
2394   shellBuildPhase->AddAttribute("shellPath",
2395                                 this->CreateString("/bin/sh"));
2396   shellBuildPhase->AddAttribute("shellScript",
2397                                 this->CreateString(
2398                                   "# shell script goes here\nexit 0"));
2399   shellBuildPhase->AddAttribute("showEnvVarsInLog",
2400                                 this->CreateString("0"));
2401
2402   cmXCodeObject* target =
2403     this->CreateObject(cmXCodeObject::PBXAggregateTarget);
2404   target->SetComment(cmtarget.GetName());
2405   cmXCodeObject* buildPhases =
2406     this->CreateObject(cmXCodeObject::OBJECT_LIST);
2407   std::vector<cmXCodeObject*> emptyContentVector;
2408   this->CreateCustomCommands(buildPhases, 0, 0, 0, emptyContentVector, 0,
2409                              cmtarget);
2410   target->AddAttribute("buildPhases", buildPhases);
2411   if(this->XcodeVersion > 20)
2412     {
2413     this->AddConfigurations(target, cmtarget);
2414     }
2415   else
2416     {
2417     const char* theConfig =
2418       this->CurrentMakefile->GetDefinition("CMAKE_BUILD_TYPE");
2419     cmXCodeObject* buildSettings =
2420       this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
2421     this->CreateBuildSettings(cmtarget, buildSettings, theConfig);
2422     target->AddAttribute("buildSettings", buildSettings);
2423     }
2424   cmXCodeObject* dependencies =
2425     this->CreateObject(cmXCodeObject::OBJECT_LIST);
2426   target->AddAttribute("dependencies", dependencies);
2427   target->AddAttribute("name", this->CreateString(cmtarget.GetName()));
2428   target->AddAttribute("productName",this->CreateString(cmtarget.GetName()));
2429   target->SetTarget(&cmtarget);
2430
2431   // Add source files without build rules for editing convenience.
2432   if(cmtarget.GetType() == cmTarget::UTILITY)
2433     {
2434     std::vector<cmSourceFile*> const& sources = cmtarget.GetSourceFiles();
2435     for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
2436         i != sources.end(); ++i)
2437       {
2438       if(!(*i)->GetPropertyAsBool("GENERATED"))
2439         {
2440         this->CreateXCodeFileReference(*i, cmtarget);
2441         }
2442       }
2443     }
2444
2445   target->SetId(this->GetOrCreateId(
2446     cmtarget.GetName(), target->GetId()).c_str());
2447
2448   return target;
2449 }
2450
2451 //----------------------------------------------------------------------------
2452 std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
2453                                                       cmTarget& cmtarget)
2454 {
2455   std::string configTypes =
2456     this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES");
2457   std::vector<std::string> configVectorIn;
2458   std::vector<std::string> configVector;
2459   configVectorIn.push_back(configTypes);
2460   cmSystemTools::ExpandList(configVectorIn, configVector);
2461   cmXCodeObject* configlist =
2462     this->CreateObject(cmXCodeObject::XCConfigurationList);
2463   cmXCodeObject* buildConfigurations =
2464     this->CreateObject(cmXCodeObject::OBJECT_LIST);
2465   configlist->AddAttribute("buildConfigurations", buildConfigurations);
2466   std::string comment = "Build configuration list for ";
2467   comment += cmXCodeObject::PBXTypeNames[target->GetIsA()];
2468   comment += " \"";
2469   comment += cmtarget.GetName();
2470   comment += "\"";
2471   configlist->SetComment(comment.c_str());
2472   target->AddAttribute("buildConfigurationList",
2473                        this->CreateObjectReference(configlist));
2474   for(unsigned int i = 0; i < configVector.size(); ++i)
2475     {
2476     cmXCodeObject* config =
2477       this->CreateObject(cmXCodeObject::XCBuildConfiguration);
2478     buildConfigurations->AddObject(config);
2479     cmXCodeObject* buildSettings =
2480       this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
2481     this->CreateBuildSettings(cmtarget, buildSettings,
2482                               configVector[i].c_str());
2483     config->AddAttribute("name", this->CreateString(configVector[i].c_str()));
2484     config->SetComment(configVector[i].c_str());
2485     config->AddAttribute("buildSettings", buildSettings);
2486     }
2487   if(configVector.size())
2488     {
2489     configlist->AddAttribute("defaultConfigurationName",
2490                              this->CreateString(configVector[0].c_str()));
2491     configlist->AddAttribute("defaultConfigurationIsVisible",
2492                              this->CreateString("0"));
2493     return configVector[0];
2494     }
2495   return "";
2496 }
2497
2498 //----------------------------------------------------------------------------
2499 const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
2500 {
2501   switch(cmtarget.GetType())
2502     {
2503     case cmTarget::OBJECT_LIBRARY:
2504     case cmTarget::STATIC_LIBRARY:
2505       return "archive.ar";
2506     case cmTarget::MODULE_LIBRARY:
2507       if (cmtarget.IsCFBundleOnApple())
2508         return "wrapper.plug-in";
2509       else
2510         return ((this->XcodeVersion >= 22)?
2511               "compiled.mach-o.executable" : "compiled.mach-o.dylib");
2512     case cmTarget::SHARED_LIBRARY:
2513       return (cmtarget.GetPropertyAsBool("FRAMEWORK")?
2514               "wrapper.framework" : "compiled.mach-o.dylib");
2515     case cmTarget::EXECUTABLE:
2516       return "compiled.mach-o.executable";
2517     default: break;
2518     }
2519   return 0;
2520 }
2521
2522 //----------------------------------------------------------------------------
2523 const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
2524 {
2525   switch(cmtarget.GetType())
2526     {
2527     case cmTarget::OBJECT_LIBRARY:
2528     case cmTarget::STATIC_LIBRARY:
2529       return "com.apple.product-type.library.static";
2530     case cmTarget::MODULE_LIBRARY:
2531       if (cmtarget.IsCFBundleOnApple())
2532         return "com.apple.product-type.bundle";
2533       else
2534         return ((this->XcodeVersion >= 22)?
2535                 "com.apple.product-type.tool" :
2536                 "com.apple.product-type.library.dynamic");
2537     case cmTarget::SHARED_LIBRARY:
2538       return (cmtarget.GetPropertyAsBool("FRAMEWORK")?
2539               "com.apple.product-type.framework" :
2540               "com.apple.product-type.library.dynamic");
2541     case cmTarget::EXECUTABLE:
2542       return (cmtarget.GetPropertyAsBool("MACOSX_BUNDLE")?
2543               "com.apple.product-type.application" :
2544               "com.apple.product-type.tool");
2545     default: break;
2546     }
2547   return 0;
2548 }
2549
2550 //----------------------------------------------------------------------------
2551 cmXCodeObject*
2552 cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
2553                                           cmXCodeObject* buildPhases)
2554 {
2555   cmXCodeObject* target =
2556     this->CreateObject(cmXCodeObject::PBXNativeTarget);
2557   target->AddAttribute("buildPhases", buildPhases);
2558   cmXCodeObject* buildRules = this->CreateObject(cmXCodeObject::OBJECT_LIST);
2559   target->AddAttribute("buildRules", buildRules);
2560   std::string defConfig;
2561   if(this->XcodeVersion > 20)
2562     {
2563     defConfig = this->AddConfigurations(target, cmtarget);
2564     }
2565   else
2566     {
2567     cmXCodeObject* buildSettings =
2568       this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
2569     defConfig = this->CurrentMakefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
2570     this->CreateBuildSettings(cmtarget, buildSettings, defConfig.c_str());
2571     target->AddAttribute("buildSettings", buildSettings);
2572     }
2573   cmXCodeObject* dependencies =
2574     this->CreateObject(cmXCodeObject::OBJECT_LIST);
2575   target->AddAttribute("dependencies", dependencies);
2576   target->AddAttribute("name", this->CreateString(cmtarget.GetName()));
2577   target->AddAttribute("productName",this->CreateString(cmtarget.GetName()));
2578
2579   cmXCodeObject* fileRef =
2580     this->CreateObject(cmXCodeObject::PBXFileReference);
2581   if(const char* fileType = this->GetTargetFileType(cmtarget))
2582     {
2583     fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
2584     }
2585   std::string fullName;
2586   if(cmtarget.GetType() == cmTarget::OBJECT_LIBRARY)
2587     {
2588     fullName = "lib";
2589     fullName += cmtarget.GetName();
2590     fullName += ".a";
2591     }
2592   else
2593     {
2594     fullName = cmtarget.GetFullName(defConfig.c_str());
2595     }
2596   fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
2597   fileRef->AddAttribute("refType", this->CreateString("0"));
2598   fileRef->AddAttribute("sourceTree",
2599                         this->CreateString("BUILT_PRODUCTS_DIR"));
2600   fileRef->SetComment(cmtarget.GetName());
2601   target->AddAttribute("productReference",
2602                        this->CreateObjectReference(fileRef));
2603   if(const char* productType = this->GetTargetProductType(cmtarget))
2604     {
2605     target->AddAttribute("productType", this->CreateString(productType));
2606     }
2607   target->SetTarget(&cmtarget);
2608   target->SetId(this->GetOrCreateId(
2609     cmtarget.GetName(), target->GetId()).c_str());
2610   return target;
2611 }
2612
2613 //----------------------------------------------------------------------------
2614 cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
2615 {
2616   if(!t)
2617     {
2618     return 0;
2619     }
2620   for(std::vector<cmXCodeObject*>::iterator i = this->XCodeObjects.begin();
2621       i != this->XCodeObjects.end(); ++i)
2622     {
2623     cmXCodeObject* o = *i;
2624     if(o->GetTarget() == t)
2625       {
2626       return o;
2627       }
2628     }
2629   return 0;
2630 }
2631
2632 //----------------------------------------------------------------------------
2633 std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name,
2634                                                   const char* id)
2635 {
2636   std::string guidStoreName = name;
2637   guidStoreName += "_GUID_CMAKE";
2638   const char* storedGUID =
2639     this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
2640
2641   if(storedGUID)
2642     {
2643     return storedGUID;
2644     }
2645
2646   this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
2647     id, "Stored Xcode object GUID", cmCacheManager::INTERNAL);
2648
2649   return id;
2650 }
2651
2652 //----------------------------------------------------------------------------
2653 void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
2654                                              cmXCodeObject* dependTarget)
2655 {
2656   // This is called once for every edge in the target dependency graph.
2657   cmXCodeObject* container =
2658     this->CreateObject(cmXCodeObject::PBXContainerItemProxy);
2659   container->SetComment("PBXContainerItemProxy");
2660   container->AddAttribute("containerPortal",
2661                           this->CreateObjectReference(this->RootObject));
2662   container->AddAttribute("proxyType", this->CreateString("1"));
2663   container->AddAttribute("remoteGlobalIDString",
2664                           this->CreateObjectReference(dependTarget));
2665   container->AddAttribute("remoteInfo",
2666                           this->CreateString(
2667                             dependTarget->GetTarget()->GetName()));
2668   cmXCodeObject* targetdep =
2669     this->CreateObject(cmXCodeObject::PBXTargetDependency);
2670   targetdep->SetComment("PBXTargetDependency");
2671   targetdep->AddAttribute("target",
2672                           this->CreateObjectReference(dependTarget));
2673   targetdep->AddAttribute("targetProxy",
2674                           this->CreateObjectReference(container));
2675
2676   cmXCodeObject* depends = target->GetObject("dependencies");
2677   if(!depends)
2678     {
2679     cmSystemTools::
2680       Error("target does not have dependencies attribute error..");
2681
2682     }
2683   else
2684     {
2685     depends->AddUniqueObject(targetdep);
2686     }
2687 }
2688
2689 //----------------------------------------------------------------------------
2690 void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
2691                                                      const char* attribute,
2692                                                      const char* value)
2693 {
2694   if(settings)
2695     {
2696     cmXCodeObject* attr = settings->GetObject(attribute);
2697     if(!attr)
2698       {
2699       settings->AddAttribute(attribute, this->CreateString(value));
2700       }
2701     else
2702       {
2703       std::string oldValue = attr->GetString();
2704       oldValue += " ";
2705       oldValue += value;
2706       attr->SetString(oldValue.c_str());
2707       }
2708     }
2709 }
2710
2711 //----------------------------------------------------------------------------
2712 void cmGlobalXCodeGenerator
2713 ::AppendBuildSettingAttribute(cmXCodeObject* target,
2714                               const char* attribute,
2715                               const char* value,
2716                               const char* configName)
2717 {
2718   if(this->XcodeVersion < 21)
2719     {
2720     // There is only one configuration.  Add the setting to the buildSettings
2721     // of the target.
2722     this->AppendOrAddBuildSetting(target->GetObject("buildSettings"),
2723                                   attribute, value);
2724     }
2725   else
2726     {
2727     // There are multiple configurations.  Add the setting to the
2728     // buildSettings of the configuration name given.
2729     cmXCodeObject* configurationList =
2730       target->GetObject("buildConfigurationList")->GetObject();
2731     cmXCodeObject* buildConfigs =
2732       configurationList->GetObject("buildConfigurations");
2733     std::vector<cmXCodeObject*> list = buildConfigs->GetObjectList();
2734     // each configuration and the target itself has a buildSettings in it
2735     //list.push_back(target);
2736     for(std::vector<cmXCodeObject*>::iterator i = list.begin();
2737         i != list.end(); ++i)
2738       {
2739       if(configName)
2740         {
2741         if(strcmp((*i)->GetObject("name")->GetString(), configName) == 0)
2742           {
2743           cmXCodeObject* settings = (*i)->GetObject("buildSettings");
2744           this->AppendOrAddBuildSetting(settings, attribute, value);
2745           }
2746         }
2747       else
2748         {
2749         cmXCodeObject* settings = (*i)->GetObject("buildSettings");
2750         this->AppendOrAddBuildSetting(settings, attribute, value);
2751         }
2752       }
2753     }
2754 }
2755
2756 //----------------------------------------------------------------------------
2757 void cmGlobalXCodeGenerator
2758 ::AddDependAndLinkInformation(cmXCodeObject* target)
2759 {
2760   cmTarget* cmtarget = target->GetTarget();
2761   if(!cmtarget)
2762     {
2763     cmSystemTools::Error("Error no target on xobject\n");
2764     return;
2765     }
2766
2767   // Add dependencies on other CMake targets.
2768   TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget);
2769   for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i)
2770     {
2771     if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i))
2772       {
2773       this->AddDependTarget(target, dptarget);
2774       }
2775     }
2776
2777   // Loop over configuration types and set per-configuration info.
2778   for(std::vector<std::string>::iterator i =
2779         this->CurrentConfigurationTypes.begin();
2780       i != this->CurrentConfigurationTypes.end(); ++i)
2781     {
2782     // Get the current configuration name.
2783     const char* configName = i->c_str();
2784     if(!*configName)
2785       {
2786       configName = 0;
2787       }
2788
2789     if(this->XcodeVersion >= 50)
2790       {
2791       // Add object library contents as link flags.
2792       std::string linkObjs;
2793       const char* sep = "";
2794       std::vector<std::string> objs;
2795       this->GetGeneratorTarget(cmtarget)->UseObjectLibraries(objs);
2796       for(std::vector<std::string>::const_iterator
2797             oi = objs.begin(); oi != objs.end(); ++oi)
2798         {
2799         linkObjs += sep;
2800         sep = " ";
2801         linkObjs += this->XCodeEscapePath(oi->c_str());
2802         }
2803       this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
2804                                         linkObjs.c_str(), configName);
2805       }
2806
2807     // Skip link information for object libraries.
2808     if(cmtarget->GetType() == cmTarget::OBJECT_LIBRARY ||
2809        cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
2810       {
2811       continue;
2812       }
2813
2814     // Compute the link library and directory information.
2815     cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
2816     if(!pcli)
2817       {
2818       continue;
2819       }
2820     cmComputeLinkInformation& cli = *pcli;
2821
2822     // Add dependencies directly on library files.
2823     {
2824     std::vector<std::string> const& libDeps = cli.GetDepends();
2825     for(std::vector<std::string>::const_iterator j = libDeps.begin();
2826         j != libDeps.end(); ++j)
2827       {
2828       target->AddDependLibrary(configName, j->c_str());
2829       }
2830     }
2831
2832     // add the library search paths
2833     {
2834     std::vector<std::string> const& libDirs = cli.GetDirectories();
2835     std::string linkDirs;
2836     for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
2837         libDir != libDirs.end(); ++libDir)
2838       {
2839       if(libDir->size() && *libDir != "/usr/lib")
2840         {
2841         if(this->XcodeVersion > 15)
2842           {
2843           // Now add the same one but append
2844           // $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it:
2845           linkDirs += " ";
2846           linkDirs += this->XCodeEscapePath(
2847             (*libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)").c_str());
2848           }
2849         linkDirs += " ";
2850         linkDirs += this->XCodeEscapePath(libDir->c_str());
2851         }
2852       }
2853     this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
2854                                       linkDirs.c_str(), configName);
2855     }
2856
2857     // now add the link libraries
2858     {
2859     std::string linkLibs;
2860     const char* sep = "";
2861     typedef cmComputeLinkInformation::ItemVector ItemVector;
2862     ItemVector const& libNames = cli.GetItems();
2863     for(ItemVector::const_iterator li = libNames.begin();
2864         li != libNames.end(); ++li)
2865       {
2866       linkLibs += sep;
2867       sep = " ";
2868       if(li->IsPath)
2869         {
2870         linkLibs += this->XCodeEscapePath(li->Value.c_str());
2871         }
2872       else
2873         {
2874         linkLibs += li->Value;
2875         }
2876       if(li->Target && !li->Target->IsImported())
2877         {
2878         target->AddDependTarget(configName, li->Target->GetName());
2879         }
2880       }
2881     this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
2882                                       linkLibs.c_str(), configName);
2883     }
2884     }
2885 }
2886
2887 //----------------------------------------------------------------------------
2888 void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
2889                                           std::vector<cmLocalGenerator*>&
2890                                           generators)
2891 {
2892   for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
2893       i != generators.end(); ++i)
2894     {
2895     if(this->IsExcluded(root, *i))
2896       {
2897       continue;
2898       }
2899     cmMakefile* mf = (*i)->GetMakefile();
2900     std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
2901     cmTargets &tgts = mf->GetTargets();
2902     for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
2903       {
2904       cmTarget& cmtarget = l->second;
2905
2906       // Same skipping logic here as in CreateXCodeTargets so that we do not
2907       // end up with (empty anyhow) ALL_BUILD and XCODE_DEPEND_HELPER source
2908       // groups:
2909       //
2910       if(cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
2911         {
2912         continue;
2913         }
2914
2915       // add the soon to be generated Info.plist file as a source for a
2916       // MACOSX_BUNDLE file
2917       if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
2918         {
2919         std::string plist = this->ComputeInfoPListLocation(cmtarget);
2920         cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
2921         cmtarget.AddSourceFile(sf);
2922         }
2923
2924       std::vector<cmSourceFile*>  classes = cmtarget.GetSourceFiles();
2925
2926       // Put cmSourceFile instances in proper groups:
2927       for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
2928           s != classes.end(); s++)
2929         {
2930         cmSourceFile* sf = *s;
2931         // Add the file to the list of sources.
2932         std::string const& source = sf->GetFullPath();
2933         cmSourceGroup& sourceGroup =
2934           mf->FindSourceGroup(source.c_str(), sourceGroups);
2935         cmXCodeObject* pbxgroup =
2936           this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
2937         cmStdString key = GetGroupMapKey(cmtarget, sf);
2938         this->GroupMap[key] = pbxgroup;
2939         }
2940
2941       // Put OBJECT_LIBRARY objects in proper groups:
2942       std::vector<std::string> objs;
2943       this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
2944       for(std::vector<std::string>::const_iterator
2945             oi = objs.begin(); oi != objs.end(); ++oi)
2946         {
2947         std::string const& source = *oi;
2948         cmSourceGroup& sourceGroup =
2949           mf->FindSourceGroup(source.c_str(), sourceGroups);
2950         cmXCodeObject* pbxgroup =
2951           this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
2952         cmStdString key = GetGroupMapKeyFromPath(cmtarget, source);
2953         this->GroupMap[key] = pbxgroup;
2954         }
2955       }
2956     }
2957 }
2958
2959 cmXCodeObject *cmGlobalXCodeGenerator
2960 ::CreatePBXGroup(cmXCodeObject *parent, cmStdString name)
2961 {
2962   cmXCodeObject* parentChildren = NULL;
2963   if(parent)
2964     parentChildren = parent->GetObject("children");
2965   cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
2966   cmXCodeObject* groupChildren =
2967   this->CreateObject(cmXCodeObject::OBJECT_LIST);
2968   group->AddAttribute("name", this->CreateString(name.c_str()));
2969   group->AddAttribute("children", groupChildren);
2970   if(this->XcodeVersion == 15)
2971   {
2972     group->AddAttribute("refType", this->CreateString("4"));
2973   }
2974   group->AddAttribute("sourceTree", this->CreateString("<group>"));
2975   if(parentChildren)
2976     parentChildren->AddObject(group);
2977   return group;
2978 }
2979
2980 //----------------------------------------------------------------------------
2981 cmXCodeObject* cmGlobalXCodeGenerator
2982 ::CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg)
2983 {
2984   cmStdString s;
2985   cmStdString target;
2986   const char *targetFolder= cmtarget.GetProperty("FOLDER");
2987   if(targetFolder) {
2988     target = targetFolder;
2989     target += "/";
2990   }
2991   target += cmtarget.GetName();
2992   s = target + "/";
2993   s += sg->GetFullName();
2994   std::map<cmStdString, cmXCodeObject* >::iterator it =
2995     this->GroupNameMap.find(s);
2996   if(it != this->GroupNameMap.end())
2997     {
2998     return it->second;
2999     }
3000
3001   it = this->TargetGroup.find(target);
3002   cmXCodeObject* tgroup = 0;
3003   if(it != this->TargetGroup.end())
3004     {
3005     tgroup = it->second;
3006     }
3007   else
3008     {
3009     std::vector<std::string> tgt_folders =
3010       cmSystemTools::tokenize(target, "/");
3011     cmStdString curr_tgt_folder;
3012     for(std::vector<std::string>::size_type i = 0; i < tgt_folders.size();i++)
3013       {
3014       curr_tgt_folder += tgt_folders[i];
3015       it = this->TargetGroup.find(curr_tgt_folder);
3016       if(it == this->TargetGroup.end())
3017         {
3018         tgroup = this->CreatePBXGroup(tgroup,tgt_folders[i]);
3019         this->TargetGroup[curr_tgt_folder] = tgroup;
3020         }
3021       else
3022         {
3023         tgroup = it->second;
3024         continue;
3025         }
3026       if(i == 0)
3027         {
3028         this->SourcesGroupChildren->AddObject(tgroup);
3029         }
3030       curr_tgt_folder += "/";
3031       }
3032     }
3033   this->TargetGroup[target] = tgroup;
3034
3035   // If it's the default source group (empty name) then put the source file
3036   // directly in the tgroup...
3037   //
3038   if (cmStdString(sg->GetFullName()) == "")
3039     {
3040     this->GroupNameMap[s] = tgroup;
3041     return tgroup;
3042     }
3043
3044   //It's a recursive folder structure, let's find the real parent group
3045   if(std::string(sg->GetFullName()) != std::string(sg->GetName()))
3046     {
3047     std::vector<std::string> folders =
3048       cmSystemTools::tokenize(sg->GetFullName(), "\\");
3049     cmStdString curr_folder = target;
3050     curr_folder += "/";
3051     for(std::vector<std::string>::size_type i = 0; i < folders.size();i++)
3052       {
3053       curr_folder += folders[i];
3054       std::map<cmStdString, cmXCodeObject* >::iterator i_folder =
3055         this->GroupNameMap.find(curr_folder);
3056       //Create new folder
3057       if(i_folder == this->GroupNameMap.end())
3058         {
3059         cmXCodeObject *group = this->CreatePBXGroup(tgroup,folders[i]);
3060         this->GroupNameMap[curr_folder] = group;
3061         tgroup = group;
3062         }
3063       else
3064         {
3065         tgroup = i_folder->second;
3066         }
3067       curr_folder = curr_folder + "\\";
3068       }
3069     return tgroup;
3070     }
3071   cmXCodeObject *group = this->CreatePBXGroup(tgroup,sg->GetName());
3072   this->GroupNameMap[s] = group;
3073   return group;
3074 }
3075
3076 //----------------------------------------------------------------------------
3077 void cmGlobalXCodeGenerator
3078 ::CreateXCodeObjects(cmLocalGenerator* root,
3079                      std::vector<cmLocalGenerator*>&
3080                      generators)
3081 {
3082   this->ClearXCodeObjects();
3083   this->RootObject = 0;
3084   this->SourcesGroupChildren = 0;
3085   this->ResourcesGroupChildren = 0;
3086   this->MainGroupChildren = 0;
3087   cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
3088   group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
3089   cmXCodeObject* developBuildStyle =
3090     this->CreateObject(cmXCodeObject::PBXBuildStyle);
3091   cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
3092   if(this->XcodeVersion == 15)
3093     {
3094     developBuildStyle->AddAttribute("name",
3095                                     this->CreateString("Development"));
3096     developBuildStyle->AddAttribute("buildSettings", group);
3097     listObjs->AddObject(developBuildStyle);
3098     group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
3099     group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("YES"));
3100     cmXCodeObject* deployBuildStyle =
3101     this->CreateObject(cmXCodeObject::PBXBuildStyle);
3102     deployBuildStyle->AddAttribute("name", this->CreateString("Deployment"));
3103     deployBuildStyle->AddAttribute("buildSettings", group);
3104     listObjs->AddObject(deployBuildStyle);
3105     }
3106   else
3107     {
3108     for(unsigned int i = 0; i < this->CurrentConfigurationTypes.size(); ++i)
3109       {
3110       cmXCodeObject* buildStyle =
3111         this->CreateObject(cmXCodeObject::PBXBuildStyle);
3112       const char* name = this->CurrentConfigurationTypes[i].c_str();
3113       buildStyle->AddAttribute("name", this->CreateString(name));
3114       buildStyle->SetComment(name);
3115       cmXCodeObject* sgroup =
3116         this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
3117       sgroup->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
3118       buildStyle->AddAttribute("buildSettings", sgroup);
3119       listObjs->AddObject(buildStyle);
3120       }
3121     }
3122
3123   cmXCodeObject* mainGroup = this->CreateObject(cmXCodeObject::PBXGroup);
3124   this->MainGroupChildren =
3125     this->CreateObject(cmXCodeObject::OBJECT_LIST);
3126   mainGroup->AddAttribute("children", this->MainGroupChildren);
3127   if(this->XcodeVersion == 15)
3128     {
3129     mainGroup->AddAttribute("refType", this->CreateString("4"));
3130     }
3131   mainGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
3132
3133   cmXCodeObject* sourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
3134   this->SourcesGroupChildren =
3135     this->CreateObject(cmXCodeObject::OBJECT_LIST);
3136   sourcesGroup->AddAttribute("name", this->CreateString("Sources"));
3137   sourcesGroup->AddAttribute("children", this->SourcesGroupChildren);
3138   if(this->XcodeVersion == 15)
3139     {
3140     sourcesGroup->AddAttribute("refType", this->CreateString("4"));
3141     }
3142   sourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
3143   this->MainGroupChildren->AddObject(sourcesGroup);
3144
3145   cmXCodeObject* resourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
3146   this->ResourcesGroupChildren =
3147     this->CreateObject(cmXCodeObject::OBJECT_LIST);
3148   resourcesGroup->AddAttribute("name", this->CreateString("Resources"));
3149   resourcesGroup->AddAttribute("children", this->ResourcesGroupChildren);
3150   if(this->XcodeVersion == 15)
3151     {
3152     resourcesGroup->AddAttribute("refType", this->CreateString("4"));
3153     }
3154   resourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
3155   this->MainGroupChildren->AddObject(resourcesGroup);
3156
3157   // now create the cmake groups
3158   this->CreateGroups(root, generators);
3159
3160   cmXCodeObject* productGroup = this->CreateObject(cmXCodeObject::PBXGroup);
3161   productGroup->AddAttribute("name", this->CreateString("Products"));
3162   if(this->XcodeVersion == 15)
3163     {
3164     productGroup->AddAttribute("refType", this->CreateString("4"));
3165     }
3166   productGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
3167   cmXCodeObject* productGroupChildren =
3168     this->CreateObject(cmXCodeObject::OBJECT_LIST);
3169   productGroup->AddAttribute("children", productGroupChildren);
3170   this->MainGroupChildren->AddObject(productGroup);
3171
3172
3173   this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
3174   this->RootObject->SetComment("Project object");
3175
3176   std::string project_id = "PROJECT_";
3177   project_id += root->GetMakefile()->GetProjectName();
3178   this->RootObject->SetId(this->GetOrCreateId(
3179     project_id.c_str(), this->RootObject->GetId()).c_str());
3180
3181   group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
3182   this->RootObject->AddAttribute("mainGroup",
3183                              this->CreateObjectReference(mainGroup));
3184   this->RootObject->AddAttribute("buildSettings", group);
3185   this->RootObject->AddAttribute("buildStyles", listObjs);
3186   this->RootObject->AddAttribute("hasScannedForEncodings",
3187                              this->CreateString("0"));
3188   if (this->XcodeVersion >= 30)
3189     {
3190     group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
3191     group->AddAttribute("BuildIndependentTargetsInParallel",
3192                         this->CreateString("YES"));
3193     this->RootObject->AddAttribute("attributes", group);
3194     if (this->XcodeVersion >= 32)
3195       this->RootObject->AddAttribute("compatibilityVersion",
3196                                      this->CreateString("Xcode 3.2"));
3197     else if (this->XcodeVersion >= 31)
3198       this->RootObject->AddAttribute("compatibilityVersion",
3199                                      this->CreateString("Xcode 3.1"));
3200     else
3201       this->RootObject->AddAttribute("compatibilityVersion",
3202                                      this->CreateString("Xcode 3.0"));
3203     }
3204   // Point Xcode at the top of the source tree.
3205   {
3206   std::string pdir =
3207     this->RelativeToBinary(root->GetMakefile()->GetCurrentDirectory());
3208   this->RootObject->AddAttribute("projectDirPath",
3209                                  this->CreateString(pdir.c_str()));
3210   this->RootObject->AddAttribute("projectRoot", this->CreateString(""));
3211   }
3212   cmXCodeObject* configlist =
3213     this->CreateObject(cmXCodeObject::XCConfigurationList);
3214   cmXCodeObject* buildConfigurations =
3215     this->CreateObject(cmXCodeObject::OBJECT_LIST);
3216   std::vector<cmXCodeObject*> configs;
3217   const char *defaultConfigName = "Debug";
3218   if(this->XcodeVersion == 15)
3219     {
3220     cmXCodeObject* configDebug =
3221       this->CreateObject(cmXCodeObject::XCBuildConfiguration);
3222     configDebug->AddAttribute("name", this->CreateString("Debug"));
3223     configs.push_back(configDebug);
3224     cmXCodeObject* configRelease =
3225       this->CreateObject(cmXCodeObject::XCBuildConfiguration);
3226     configRelease->AddAttribute("name", this->CreateString("Release"));
3227     configs.push_back(configRelease);
3228     }
3229   else
3230     {
3231     for(unsigned int i = 0; i < this->CurrentConfigurationTypes.size(); ++i)
3232       {
3233       const char* name = this->CurrentConfigurationTypes[i].c_str();
3234       if (0 == i)
3235         {
3236         defaultConfigName = name;
3237         }
3238       cmXCodeObject* config =
3239         this->CreateObject(cmXCodeObject::XCBuildConfiguration);
3240       config->AddAttribute("name", this->CreateString(name));
3241       configs.push_back(config);
3242       }
3243     }
3244   for(std::vector<cmXCodeObject*>::iterator c = configs.begin();
3245       c != configs.end(); ++c)
3246     {
3247     buildConfigurations->AddObject(*c);
3248     }
3249   configlist->AddAttribute("buildConfigurations", buildConfigurations);
3250
3251   std::string comment = "Build configuration list for PBXProject ";
3252   comment += " \"";
3253   comment += this->CurrentProject;
3254   comment += "\"";
3255   configlist->SetComment(comment.c_str());
3256   configlist->AddAttribute("defaultConfigurationIsVisible",
3257                            this->CreateString("0"));
3258   configlist->AddAttribute("defaultConfigurationName",
3259                            this->CreateString(defaultConfigName));
3260   cmXCodeObject* buildSettings =
3261       this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
3262   const char* osxArch =
3263       this->CurrentMakefile->GetDefinition("CMAKE_OSX_ARCHITECTURES");
3264   if(!osxArch || strlen(osxArch) == 0)
3265     {
3266     if(this->XcodeVersion >= 32)
3267       {
3268       osxArch = "$(ARCHS_STANDARD_32_64_BIT)";
3269       }
3270     else if(this->XcodeVersion == 31)
3271       {
3272       osxArch = "$(ARCHS_STANDARD_32_BIT)";
3273       }
3274     else if(this->XcodeVersion <= 30)
3275       {
3276 #ifdef __ppc__
3277       osxArch = "ppc";
3278 #endif
3279 #ifdef __i386
3280       osxArch = "i386";
3281 #endif
3282       }
3283     buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
3284                                 this->CreateString("YES"));
3285     }
3286
3287   const char* sysroot =
3288       this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT");
3289   const char* deploymentTarget =
3290     this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
3291   if(osxArch && sysroot)
3292     {
3293     // recompute this as it may have been changed since enable language
3294     this->Architectures.clear();
3295     cmSystemTools::ExpandListArgument(std::string(osxArch),
3296                                       this->Architectures);
3297     buildSettings->AddAttribute("SDKROOT",
3298                                 this->CreateString(sysroot));
3299     std::string archString;
3300     const char* sep = "";
3301     for( std::vector<std::string>::iterator i =
3302            this->Architectures.begin();
3303          i != this->Architectures.end(); ++i)
3304       {
3305       archString += sep;
3306       archString += *i;
3307       sep = " ";
3308       }
3309     buildSettings->AddAttribute("ARCHS",
3310                                 this->CreateString(archString.c_str()));
3311     }
3312   if(deploymentTarget && *deploymentTarget)
3313     {
3314     buildSettings->AddAttribute("MACOSX_DEPLOYMENT_TARGET",
3315                                 this->CreateString(deploymentTarget));
3316     }
3317   if(!this->PlatformToolset.empty())
3318     {
3319     buildSettings->AddAttribute("GCC_VERSION",
3320       this->CreateString(this->PlatformToolset.c_str()));
3321     }
3322
3323   // Put this last so it can override existing settings
3324   // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
3325   {
3326     std::vector<std::string> vars = this->CurrentMakefile->GetDefinitions();
3327     for(std::vector<std::string>::const_iterator i = vars.begin();
3328         i != vars.end(); ++i)
3329     {
3330       if(i->find("CMAKE_XCODE_ATTRIBUTE_") == 0)
3331       {
3332         buildSettings->AddAttribute(i->substr(22).c_str(),
3333           this->CreateString(
3334             this->CurrentMakefile->GetDefinition(i->c_str())));
3335       }
3336     }
3337   }
3338
3339   std::string symroot = root->GetMakefile()->GetCurrentOutputDirectory();
3340   symroot += "/build";
3341   buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot.c_str()));
3342
3343   for( std::vector<cmXCodeObject*>::iterator i = configs.begin();
3344        i != configs.end(); ++i)
3345     {
3346     (*i)->AddAttribute("buildSettings", buildSettings);
3347     }
3348
3349   this->RootObject->AddAttribute("buildConfigurationList",
3350                              this->CreateObjectReference(configlist));
3351
3352   std::vector<cmXCodeObject*> targets;
3353   for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
3354       i != generators.end(); ++i)
3355     {
3356     if(!this->IsExcluded(root, *i))
3357       {
3358       this->CreateXCodeTargets(*i, targets);
3359       }
3360     }
3361   // loop over all targets and add link and depend info
3362   for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
3363       i != targets.end(); ++i)
3364     {
3365     cmXCodeObject* t = *i;
3366     this->AddDependAndLinkInformation(t);
3367     }
3368   if(this->XcodeVersion < 50)
3369     {
3370     // now create xcode depend hack makefile
3371     this->CreateXCodeDependHackTarget(targets);
3372     }
3373   // now add all targets to the root object
3374   cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST);
3375   for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
3376       i != targets.end(); ++i)
3377     {
3378     cmXCodeObject* t = *i;
3379     allTargets->AddObject(t);
3380     cmXCodeObject* productRef = t->GetObject("productReference");
3381     if(productRef)
3382       {
3383       productGroupChildren->AddObject(productRef->GetObject());
3384       }
3385     }
3386   this->RootObject->AddAttribute("targets", allTargets);
3387 }
3388
3389 //----------------------------------------------------------------------------
3390 std::string
3391 cmGlobalXCodeGenerator::GetObjectsNormalDirectory(
3392   const std::string &projName,
3393   const std::string &configName,
3394   const cmTarget *t) const
3395 {
3396   std::string dir =
3397     t->GetMakefile()->GetCurrentOutputDirectory();
3398   dir += "/";
3399   dir += projName;
3400   dir += ".build/";
3401   dir += configName;
3402   dir += "/";
3403   dir += t->GetName();
3404   dir += ".build/Objects-normal/";
3405
3406   return dir;
3407 }
3408
3409 //----------------------------------------------------------------------------
3410 void
3411 cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
3412   std::vector<cmXCodeObject*>& targets)
3413 {
3414   cmGeneratedFileStream
3415     makefileStream(this->CurrentXCodeHackMakefile.c_str());
3416   if(!makefileStream)
3417     {
3418     cmSystemTools::Error("Could not create",
3419                          this->CurrentXCodeHackMakefile.c_str());
3420     return;
3421     }
3422   makefileStream.SetCopyIfDifferent(true);
3423   // one more pass for external depend information not handled
3424   // correctly by xcode
3425   makefileStream << "# DO NOT EDIT\n";
3426   makefileStream << "# This makefile makes sure all linkable targets are\n";
3427   makefileStream << "# up-to-date with anything they link to\n"
3428     "default:\n"
3429     "\techo \"Do not invoke directly\"\n"
3430     "\n";
3431   makefileStream
3432     << "# For each target create a dummy rule "
3433     "so the target does not have to exist\n";
3434   std::set<cmStdString> emitted;
3435   for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
3436       i != targets.end(); ++i)
3437     {
3438     cmXCodeObject* target = *i;
3439     std::map<cmStdString, cmXCodeObject::StringVec> const& deplibs =
3440       target->GetDependLibraries();
3441     for(std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator ci
3442           = deplibs.begin(); ci != deplibs.end(); ++ci)
3443       {
3444       for(cmXCodeObject::StringVec::const_iterator d = ci->second.begin();
3445           d != ci->second.end(); ++d)
3446         {
3447         if(emitted.insert(*d).second)
3448           {
3449           makefileStream <<
3450             this->ConvertToRelativeForMake(d->c_str()) << ":\n";
3451           }
3452         }
3453       }
3454     }
3455   makefileStream << "\n\n";
3456
3457   // Write rules to help Xcode relink things at the right time.
3458   makefileStream <<
3459     "# Rules to remove targets that are older than anything to which they\n"
3460     "# link.  This forces Xcode to relink the targets from scratch.  It\n"
3461     "# does not seem to check these dependencies itself.\n";
3462   for(std::vector<std::string>::const_iterator
3463         ct = this->CurrentConfigurationTypes.begin();
3464       ct != this->CurrentConfigurationTypes.end(); ++ct)
3465     {
3466     const char* configName = 0;
3467     if(!ct->empty())
3468       {
3469       configName = ct->c_str();
3470       }
3471     for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
3472         i != targets.end(); ++i)
3473       {
3474       cmXCodeObject* target = *i;
3475       cmTarget* t =target->GetTarget();
3476
3477       if(t->GetType() == cmTarget::EXECUTABLE ||
3478 // Nope - no post-build for OBJECT_LIRBRARY
3479 //         t->GetType() == cmTarget::OBJECT_LIBRARY ||
3480          t->GetType() == cmTarget::STATIC_LIBRARY ||
3481          t->GetType() == cmTarget::SHARED_LIBRARY ||
3482          t->GetType() == cmTarget::MODULE_LIBRARY)
3483         {
3484         // Declare an entry point for the target post-build phase.
3485         makefileStream << this->PostBuildMakeTarget(t->GetName(), *ct)
3486                        << ":\n";
3487         }
3488
3489       if(t->GetType() == cmTarget::EXECUTABLE ||
3490          t->GetType() == cmTarget::SHARED_LIBRARY ||
3491          t->GetType() == cmTarget::MODULE_LIBRARY)
3492         {
3493         std::string tfull = t->GetFullPath(configName);
3494         std::string trel = this->ConvertToRelativeForMake(tfull.c_str());
3495
3496         // Add this target to the post-build phases of its dependencies.
3497         std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
3498           y = target->GetDependTargets().find(*ct);
3499         if(y != target->GetDependTargets().end())
3500           {
3501           std::vector<cmStdString> const& deptgts = y->second;
3502           for(std::vector<cmStdString>::const_iterator d = deptgts.begin();
3503               d != deptgts.end(); ++d)
3504             {
3505             makefileStream << this->PostBuildMakeTarget(*d, *ct) << ": "
3506                            << trel << "\n";
3507             }
3508           }
3509
3510         // Create a rule for this target.
3511         makefileStream << trel << ":";
3512
3513         // List dependencies if any exist.
3514         std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
3515           x = target->GetDependLibraries().find(*ct);
3516         if(x != target->GetDependLibraries().end())
3517           {
3518           std::vector<cmStdString> const& deplibs = x->second;
3519           for(std::vector<cmStdString>::const_iterator d = deplibs.begin();
3520               d != deplibs.end(); ++d)
3521             {
3522             makefileStream << "\\\n\t" <<
3523               this->ConvertToRelativeForMake(d->c_str());
3524             }
3525           }
3526         // Write the action to remove the target if it is out of date.
3527         makefileStream << "\n";
3528         makefileStream << "\t/bin/rm -f "
3529                        << this->ConvertToRelativeForMake(tfull.c_str())
3530                        << "\n";
3531         // if building for more than one architecture
3532         // then remove those exectuables as well
3533         if(this->Architectures.size() > 1)
3534           {
3535           std::string universal = this->GetObjectsNormalDirectory(
3536             this->CurrentProject, configName, t);
3537           for( std::vector<std::string>::iterator arch =
3538                  this->Architectures.begin();
3539                arch != this->Architectures.end(); ++arch)
3540             {
3541             std::string universalFile = universal;
3542             universalFile += *arch;
3543             universalFile += "/";
3544             universalFile += t->GetFullName(configName);
3545             makefileStream << "\t/bin/rm -f "
3546                            <<
3547               this->ConvertToRelativeForMake(universalFile.c_str())
3548                            << "\n";
3549             }
3550           }
3551         makefileStream << "\n\n";
3552         }
3553       }
3554     }
3555 }
3556
3557 //----------------------------------------------------------------------------
3558 void
3559 cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
3560                                            std::vector<cmLocalGenerator*>&
3561                                            generators)
3562 {
3563   if(generators.size() == 0)
3564     {
3565     return;
3566     }
3567   // Skip local generators that are excluded from this project.
3568   for(std::vector<cmLocalGenerator*>::iterator g = generators.begin();
3569       g != generators.end(); ++g)
3570     {
3571     if(this->IsExcluded(root, *g))
3572       {
3573       continue;
3574       }
3575     }
3576
3577   this->CreateXCodeObjects(root,
3578                            generators);
3579   std::string xcodeDir = root->GetMakefile()->GetStartOutputDirectory();
3580   xcodeDir += "/";
3581   xcodeDir += root->GetMakefile()->GetProjectName();
3582   xcodeDir += ".xcode";
3583   if(this->XcodeVersion > 20)
3584     {
3585     xcodeDir += "proj";
3586     }
3587   cmSystemTools::MakeDirectory(xcodeDir.c_str());
3588   std::string xcodeProjFile = xcodeDir + "/project.pbxproj";
3589   cmGeneratedFileStream fout(xcodeProjFile.c_str());
3590   fout.SetCopyIfDifferent(true);
3591   if(!fout)
3592     {
3593     return;
3594     }
3595   this->WriteXCodePBXProj(fout, root, generators);
3596   this->ClearXCodeObjects();
3597
3598   // Since this call may have created new cache entries, save the cache:
3599   //
3600   root->GetMakefile()->GetCacheManager()->SaveCache(
3601     root->GetMakefile()->GetHomeOutputDirectory());
3602 }
3603
3604 //----------------------------------------------------------------------------
3605 void
3606 cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
3607                                           cmLocalGenerator* ,
3608                                           std::vector<cmLocalGenerator*>& )
3609 {
3610   fout << "// !$*UTF8*$!\n";
3611   fout << "{\n";
3612   cmXCodeObject::Indent(1, fout);
3613   fout << "archiveVersion = 1;\n";
3614   cmXCodeObject::Indent(1, fout);
3615   fout << "classes = {\n";
3616   cmXCodeObject::Indent(1, fout);
3617   fout << "};\n";
3618   cmXCodeObject::Indent(1, fout);
3619   if(this->XcodeVersion >= 21)
3620     {
3621     if (this->XcodeVersion >= 32)
3622       fout << "objectVersion = 46;\n";
3623     else if (this->XcodeVersion >= 31)
3624       fout << "objectVersion = 45;\n";
3625     else if (this->XcodeVersion >= 30)
3626       fout << "objectVersion = 44;\n";
3627     else
3628       fout << "objectVersion = 42;\n";
3629     cmXCode21Object::PrintList(this->XCodeObjects, fout);
3630     }
3631   else
3632     {
3633     fout << "objectVersion = 39;\n";
3634     cmXCodeObject::PrintList(this->XCodeObjects, fout);
3635     }
3636   cmXCodeObject::Indent(1, fout);
3637   fout << "rootObject = " << this->RootObject->GetId() << ";\n";
3638   fout << "}\n";
3639 }
3640
3641 //----------------------------------------------------------------------------
3642 const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
3643 {
3644   return this->XcodeVersion >= 21 ?
3645     "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
3646 }
3647
3648 //----------------------------------------------------------------------------
3649 void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
3650 {
3651   entry.Name = cmGlobalXCodeGenerator::GetActualName();
3652   entry.Brief = "Generate Xcode project files.";
3653   entry.Full = "";
3654 }
3655
3656 //----------------------------------------------------------------------------
3657 std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
3658 {
3659   if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
3660     {
3661     return cmSystemTools::ConvertToOutputPath(p);
3662     }
3663   else
3664     {
3665     std::string ret =
3666       this->CurrentLocalGenerator->
3667         ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p);
3668     return cmSystemTools::ConvertToOutputPath(ret.c_str());
3669     }
3670 }
3671
3672 //----------------------------------------------------------------------------
3673 std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
3674 {
3675   if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
3676     {
3677     return cmSystemTools::ConvertToOutputPath(p);
3678     }
3679   else
3680     {
3681     std::string ret =
3682       this->CurrentLocalGenerator->
3683         ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
3684     return cmSystemTools::ConvertToOutputPath(ret.c_str());
3685     }
3686 }
3687
3688 //----------------------------------------------------------------------------
3689 std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
3690 {
3691   // We force conversion because Xcode breakpoints do not work unless
3692   // they are in a file named relative to the source tree.
3693   return this->CurrentLocalGenerator->
3694     ConvertToRelativePath(this->ProjectSourceDirectoryComponents, p, true);
3695 }
3696
3697 //----------------------------------------------------------------------------
3698 std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p)
3699 {
3700   return this->CurrentLocalGenerator->
3701     ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
3702 }
3703
3704 //----------------------------------------------------------------------------
3705 std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p)
3706 {
3707   std::string ret = p;
3708   if(ret.find(' ') != ret.npos)
3709     {
3710     std::string t = ret;
3711     ret = "\"";
3712     ret += t;
3713     ret += "\"";
3714     }
3715   return ret;
3716 }
3717
3718 //----------------------------------------------------------------------------
3719 void
3720 cmGlobalXCodeGenerator
3721 ::AppendDirectoryForConfig(const char* prefix,
3722                            const char* config,
3723                            const char* suffix,
3724                            std::string& dir)
3725 {
3726   if(this->XcodeVersion > 20)
3727     {
3728     if(config)
3729       {
3730       dir += prefix;
3731       dir += config;
3732       dir += suffix;
3733       }
3734     }
3735 }
3736
3737 //----------------------------------------------------------------------------
3738 std::string cmGlobalXCodeGenerator::LookupFlags(const char* varNamePrefix,
3739                                                 const char* varNameLang,
3740                                                 const char* varNameSuffix,
3741                                                 const char* default_flags)
3742 {
3743   if(varNameLang)
3744     {
3745     std::string varName = varNamePrefix;
3746     varName += varNameLang;
3747     varName += varNameSuffix;
3748     if(const char* varValue =
3749        this->CurrentMakefile->GetDefinition(varName.c_str()))
3750       {
3751       if(*varValue)
3752         {
3753         return varValue;
3754         }
3755       }
3756     }
3757   return default_flags;
3758 }
3759
3760 //----------------------------------------------------------------------------
3761 void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
3762                                            const char* defines_list,
3763                                            bool dflag)
3764 {
3765   // Skip this if there are no definitions.
3766   if(!defines_list)
3767     {
3768     return;
3769     }
3770
3771   // Expand the list of definitions.
3772   std::vector<std::string> defines;
3773   cmSystemTools::ExpandListArgument(defines_list, defines);
3774
3775   // Store the definitions in the string.
3776   this->AppendDefines(defs, defines, dflag);
3777 }
3778
3779 //----------------------------------------------------------------------------
3780 void
3781 cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
3782                                       std::vector<std::string> const& defines,
3783                                       bool dflag)
3784 {
3785   // GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions.
3786   std::string def;
3787   for(std::vector<std::string>::const_iterator di = defines.begin();
3788       di != defines.end(); ++di)
3789     {
3790     // Start with -D if requested.
3791     def = dflag? "-D": "";
3792     def += *di;
3793
3794     // Append the flag with needed escapes.
3795     std::string tmp;
3796     this->AppendFlag(tmp, def);
3797     defs.Add(tmp.c_str());
3798     }
3799 }
3800
3801 //----------------------------------------------------------------------------
3802 void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
3803                                         std::string const& flag)
3804 {
3805   // Short-circuit for an empty flag.
3806   if(flag.empty())
3807     {
3808     return;
3809     }
3810
3811   // Separate from previous flags.
3812   if(!flags.empty())
3813     {
3814     flags += " ";
3815     }
3816
3817   // Check if the flag needs quoting.
3818   bool quoteFlag =
3819     flag.find_first_of("`~!@#$%^&*()+={}[]|:;\"'<>,.? ") != flag.npos;
3820
3821   // We escape a flag as follows:
3822   //   - Place each flag in single quotes ''
3823   //   - Escape a single quote as \\'
3824   //   - Escape a backslash as \\\\ since it itself is an escape
3825   // Note that in the code below we need one more level of escapes for
3826   // C string syntax in this source file.
3827   //
3828   // The final level of escaping is done when the string is stored
3829   // into the project file by cmXCodeObject::PrintString.
3830
3831   if(quoteFlag)
3832     {
3833     // Open single quote.
3834     flags += "'";
3835     }
3836
3837   // Flag value with escaped quotes and backslashes.
3838   for(const char* c = flag.c_str(); *c; ++c)
3839     {
3840     if(*c == '\'')
3841       {
3842       if (this->XcodeVersion >= 40)
3843         {
3844         flags += "'\\\\''";
3845         }
3846       else
3847         {
3848         flags += "\\\\'";
3849         }
3850       }
3851     else if(*c == '\\')
3852       {
3853       flags += "\\\\\\\\";
3854       }
3855     else
3856       {
3857       flags += *c;
3858       }
3859     }
3860
3861   if(quoteFlag)
3862     {
3863     // Close single quote.
3864     flags += "'";
3865     }
3866 }
3867
3868 //----------------------------------------------------------------------------
3869 std::string
3870 cmGlobalXCodeGenerator::ComputeInfoPListLocation(cmTarget& target)
3871 {
3872   std::string plist = target.GetMakefile()->GetCurrentOutputDirectory();
3873   plist += cmake::GetCMakeFilesDirectory();
3874   plist += "/";
3875   plist += target.GetName();
3876   plist += ".dir/Info.plist";
3877   return plist;
3878 }
3879
3880 //----------------------------------------------------------------------------
3881 // Return true if the generated build tree may contain multiple builds.
3882 // i.e. "Can I build Debug and Release in the same tree?"
3883 bool cmGlobalXCodeGenerator::IsMultiConfig()
3884 {
3885   // Old Xcode 1.5 is single config:
3886   if(this->XcodeVersion == 15)
3887     {
3888     return false;
3889     }
3890
3891   // Newer Xcode versions are multi config:
3892   return true;
3893 }
3894
3895  //----------------------------------------------------------------------------
3896 void
3897 cmGlobalXCodeGenerator
3898 ::ComputeTargetObjects(cmGeneratorTarget* gt) const
3899 {
3900   // Count the number of object files with each name. Warn about duplicate
3901   // names since Xcode names them uniquely automatically with a numeric suffix
3902   // to avoid exact duplicate file names. Note that Mac file names are not
3903   // typically case sensitive, hence the LowerCase.
3904   std::map<cmStdString, int> counts;
3905   for(std::vector<cmSourceFile*>::const_iterator
3906       si = gt->ObjectSources.begin();
3907       si != gt->ObjectSources.end(); ++si)
3908     {
3909     cmSourceFile* sf = *si;
3910     std::string objectName =
3911       cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
3912     objectName += ".o";
3913
3914     std::string objectNameLower = cmSystemTools::LowerCase(objectName);
3915     counts[objectNameLower] += 1;
3916     if (2 == counts[objectNameLower])
3917       {
3918       // TODO: emit warning about duplicate name?
3919       }
3920
3921     gt->Objects[sf] = objectName;
3922     }
3923
3924   const char* configName = this->GetCMakeCFGIntDir();
3925   std::string dir = this->GetObjectsNormalDirectory(
3926     "$(PROJECT_NAME)", configName, gt->Target);
3927   if(this->XcodeVersion >= 21)
3928     {
3929     dir += "$(CURRENT_ARCH)/";
3930     }
3931   else
3932     {
3933 #ifdef __ppc__
3934     dir += "ppc/";
3935 #endif
3936 #ifdef __i386
3937     dir += "i386/";
3938 #endif
3939     }
3940   gt->ObjectDirectory = dir;
3941 }