Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmGlobalGenerator.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 #if defined(_WIN32) && !defined(__CYGWIN__)
13 #include "windows.h" // this must be first to define GetCurrentDirectory
14 #endif
15
16 #include "cmGlobalGenerator.h"
17 #include "cmLocalGenerator.h"
18 #include "cmExternalMakefileProjectGenerator.h"
19 #include "cmake.h"
20 #include "cmMakefile.h"
21 #include "cmQtAutomoc.h"
22 #include "cmSourceFile.h"
23 #include "cmVersion.h"
24 #include "cmExportInstallFileGenerator.h"
25 #include "cmComputeTargetDepends.h"
26 #include "cmGeneratedFileStream.h"
27 #include "cmGeneratorTarget.h"
28
29 #include <cmsys/Directory.hxx>
30
31 #if defined(CMAKE_BUILD_WITH_CMAKE)
32 # include <cmsys/MD5.h>
33 #endif
34
35 #include <stdlib.h> // required for atof
36
37 #include <assert.h>
38
39 cmGlobalGenerator::cmGlobalGenerator()
40 {
41   // By default the .SYMBOLIC dependency is not needed on symbolic rules.
42   this->NeedSymbolicMark = false;
43
44   // by default use the native paths
45   this->ForceUnixPaths = false;
46
47   // By default do not try to support color.
48   this->ToolSupportsColor = false;
49
50   // By default do not use link scripts.
51   this->UseLinkScript = false;
52
53   // Whether an install target is needed.
54   this->InstallTargetEnabled = false;
55
56   // how long to let try compiles run
57   this->TryCompileTimeout = 0;
58
59   this->ExtraGenerator = 0;
60   this->CurrentLocalGenerator = 0;
61   this->TryCompileOuterMakefile = 0;
62 }
63
64 cmGlobalGenerator::~cmGlobalGenerator()
65 {
66   // Delete any existing cmLocalGenerators
67   for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
68     {
69     delete this->LocalGenerators[i];
70     }
71   this->LocalGenerators.clear();
72
73   if (this->ExtraGenerator)
74     {
75     delete this->ExtraGenerator;
76     }
77
78   this->ClearGeneratorTargets();
79   this->ClearExportSets();
80 }
81
82 void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
83                                                 cmMakefile *mf,
84                                                 bool optional) {
85   std::string langComp = "CMAKE_";
86   langComp += lang;
87   langComp += "_COMPILER";
88
89   if(!mf->GetDefinition(langComp.c_str()))
90     {
91     if(!optional)
92       {
93       cmSystemTools::Error(langComp.c_str(),
94                            " not set, after EnableLanguage");
95       }
96     return;
97     }
98   const char* name = mf->GetRequiredDefinition(langComp.c_str());
99   std::string path;
100   if(!cmSystemTools::FileIsFullPath(name))
101     {
102     path = cmSystemTools::FindProgram(name);
103     }
104   else
105     {
106     path = name;
107     }
108   if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str()))
109       && (optional==false))
110     {
111     std::string message = "your ";
112     message += lang;
113     message += " compiler: \"";
114     message +=  name;
115     message += "\" was not found.   Please set ";
116     message += langComp;
117     message += " to a valid compiler path or name.";
118     cmSystemTools::Error(message.c_str());
119     path = name;
120     }
121   std::string doc = lang;
122   doc += " compiler.";
123   const char* cname = this->GetCMakeInstance()->
124     GetCacheManager()->GetCacheValue(langComp.c_str());
125   std::string changeVars;
126   if(cname && (path != cname) && (optional==false))
127     {
128     std::string cnameString = cname;
129     std::string pathString = path;
130     // get rid of potentially multiple slashes:
131     cmSystemTools::ConvertToUnixSlashes(cnameString);
132     cmSystemTools::ConvertToUnixSlashes(pathString);
133     if (cnameString != pathString)
134       {
135       const char* cvars =
136         this->GetCMakeInstance()->GetProperty(
137           "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
138       if(cvars)
139         {
140         changeVars += cvars;
141         changeVars += ";";
142         }
143       changeVars += langComp;
144       changeVars += ";";
145       changeVars += cname;
146       this->GetCMakeInstance()->SetProperty(
147         "__CMAKE_DELETE_CACHE_CHANGE_VARS_",
148         changeVars.c_str());
149       }
150     }
151   mf->AddCacheDefinition(langComp.c_str(), path.c_str(),
152                          doc.c_str(), cmCacheManager::FILEPATH);
153 }
154
155 // Find the make program for the generator, required for try compiles
156 void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
157 {
158   if(this->FindMakeProgramFile.size() == 0)
159     {
160     cmSystemTools::Error(
161       "Generator implementation error, "
162       "all generators must specify this->FindMakeProgramFile");
163     }
164   if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
165      || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
166     {
167     std::string setMakeProgram =
168       mf->GetModulesFile(this->FindMakeProgramFile.c_str());
169     if(setMakeProgram.size())
170       {
171       mf->ReadListFile(0, setMakeProgram.c_str());
172       }
173     }
174   if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
175      || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
176     {
177     cmOStringStream err;
178     err << "CMake was unable to find a build program corresponding to \""
179         << this->GetName() << "\".  CMAKE_MAKE_PROGRAM is not set.  You "
180         << "probably need to select a different build tool.";
181     cmSystemTools::Error(err.str().c_str());
182     cmSystemTools::SetFatalErrorOccured();
183     return;
184     }
185   std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
186   // if there are spaces in the make program use short path
187   // but do not short path the actual program name, as
188   // this can cause trouble with VSExpress
189   if(makeProgram.find(' ') != makeProgram.npos)
190     {
191     std::string dir;
192     std::string file;
193     cmSystemTools::SplitProgramPath(makeProgram.c_str(),
194                                     dir, file);
195     std::string saveFile = file;
196     cmSystemTools::GetShortPath(makeProgram.c_str(), makeProgram);
197     cmSystemTools::SplitProgramPath(makeProgram.c_str(),
198                                     dir, file);
199     makeProgram = dir;
200     makeProgram += "/";
201     makeProgram += saveFile;
202     mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
203                            "make program",
204                            cmCacheManager::FILEPATH);
205     }
206
207   if(makeProgram.find("xcodebuild") != makeProgram.npos)
208     {
209     // due to the text file busy /bin/sh problem with xcodebuild
210     // use the cmakexbuild wrapper instead.  This program
211     // will run xcodebuild and if it sees the error text file busy
212     // it will stop forwarding output, and let the build finish.
213     // Then it will retry the build.  It will continue this
214     // untill no text file busy errors occur.
215     std::string cmakexbuild =
216       this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
217     cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
218     cmakexbuild += "cmakexbuild";
219
220     mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM",
221                            cmakexbuild.c_str(),
222                            "make program",
223                            cmCacheManager::FILEPATH);
224     }
225 }
226
227 // enable the given language
228 //
229 // The following files are loaded in this order:
230 //
231 // First figure out what OS we are running on:
232 //
233 // CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake
234 //   CMakeDetermineSystem.cmake - figure out os info and create
235 //                                CMakeSystem.cmake IF CMAKE_SYSTEM
236 //                                not set
237 //   CMakeSystem.cmake - configured file created by
238 //                       CMakeDetermineSystem.cmake IF CMAKE_SYSTEM_LOADED
239
240 // Next try and enable all languages found in the languages vector
241 //
242 // FOREACH LANG in languages
243 //   CMake(LANG)Compiler.cmake - configured file create by
244 //                               CMakeDetermine(LANG)Compiler.cmake
245 //     CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
246 //                                          creates CMake(LANG)Compiler.cmake
247 //     CMake(LANG)Compiler.cmake - configured file created by
248 //                                 CMakeDetermine(LANG)Compiler.cmake
249 //
250 // CMakeSystemSpecificInformation.cmake
251 //   - includes Platform/${CMAKE_SYSTEM_NAME}.cmake
252 //     may use compiler stuff
253
254 // FOREACH LANG in languages
255 //   CMake(LANG)Information.cmake
256 //     - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake
257 //   CMakeTest(LANG)Compiler.cmake
258 //     - Make sure the compiler works with a try compile if
259 //       CMakeDetermine(LANG) was loaded
260 //
261 // Now load a few files that can override values set in any of the above
262 // (PROJECTNAME)Compatibility.cmake
263 //   - load any backwards compatibility stuff for current project
264 // ${CMAKE_USER_MAKE_RULES_OVERRIDE}
265 //   - allow users a chance to override system variables
266 //
267 //
268
269 void
270 cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
271                                   cmMakefile *mf, bool)
272 {
273   if(languages.size() == 0)
274     {
275     cmSystemTools::Error("EnableLanguage must have a lang specified!");
276     cmSystemTools::SetFatalErrorOccured();
277     return;
278     }
279
280   if(this->TryCompileOuterMakefile)
281     {
282     // In a try-compile we can only enable languages provided by caller.
283     for(std::vector<std::string>::const_iterator li = languages.begin();
284         li != languages.end(); ++li)
285       {
286       if(*li == "NONE")
287         {
288         this->SetLanguageEnabled("NONE", mf);
289         }
290       else
291         {
292         const char* lang = li->c_str();
293         if(this->LanguagesReady.find(lang) == this->LanguagesReady.end())
294           {
295           cmOStringStream e;
296           e << "The test project needs language "
297             << lang << " which is not enabled.";
298           this->TryCompileOuterMakefile
299             ->IssueMessage(cmake::FATAL_ERROR, e.str());
300           cmSystemTools::SetFatalErrorOccured();
301           return;
302           }
303         }
304       }
305     }
306
307   mf->AddDefinition("RUN_CONFIGURE", true);
308   std::string rootBin = mf->GetHomeOutputDirectory();
309   rootBin += cmake::GetCMakeFilesDirectory();
310
311   // If the configuration files path has been set,
312   // then we are in a try compile and need to copy the enable language
313   // files from the parent cmake bin dir, into the try compile bin dir
314   if(this->ConfiguredFilesPath.size())
315     {
316     rootBin = this->ConfiguredFilesPath;
317     }
318
319   // set the dir for parent files so they can be used by modules
320   mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str());
321
322   // find and make sure CMAKE_MAKE_PROGRAM is defined
323   this->FindMakeProgram(mf);
324
325   // try and load the CMakeSystem.cmake if it is there
326   std::string fpath = rootBin;
327   if(!mf->GetDefinition("CMAKE_SYSTEM_LOADED"))
328     {
329     fpath += "/CMakeSystem.cmake";
330     if(cmSystemTools::FileExists(fpath.c_str()))
331       {
332       mf->ReadListFile(0,fpath.c_str());
333       }
334     }
335   //  Load the CMakeDetermineSystem.cmake file and find out
336   // what platform we are running on
337   if (!mf->GetDefinition("CMAKE_SYSTEM"))
338     {
339 #if defined(_WIN32) && !defined(__CYGWIN__)
340     /* Windows version number data.  */
341     OSVERSIONINFO osvi;
342     ZeroMemory(&osvi, sizeof(osvi));
343     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
344     GetVersionEx (&osvi);
345     cmOStringStream windowsVersionString;
346     windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
347     windowsVersionString.str();
348     mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
349                       windowsVersionString.str().c_str());
350 #endif
351     // Read the DetermineSystem file
352     std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
353     mf->ReadListFile(0, systemFile.c_str());
354     // load the CMakeSystem.cmake from the binary directory
355     // this file is configured by the CMakeDetermineSystem.cmake file
356     fpath = rootBin;
357     fpath += "/CMakeSystem.cmake";
358     mf->ReadListFile(0,fpath.c_str());
359     }
360   std::map<cmStdString, bool> needTestLanguage;
361   std::map<cmStdString, bool> needSetLanguageEnabledMaps;
362   // foreach language
363   // load the CMakeDetermine(LANG)Compiler.cmake file to find
364   // the compiler
365
366   for(std::vector<std::string>::const_iterator l = languages.begin();
367       l != languages.end(); ++l)
368     {
369     const char* lang = l->c_str();
370     needSetLanguageEnabledMaps[lang] = false;
371     if(*l == "NONE")
372       {
373       this->SetLanguageEnabled("NONE", mf);
374       continue;
375       }
376     std::string loadedLang = "CMAKE_";
377     loadedLang +=  lang;
378     loadedLang += "_COMPILER_LOADED";
379     // If the existing build tree was already configured with this
380     // version of CMake then try to load the configured file first
381     // to avoid duplicate compiler tests.
382     unsigned int cacheMajor = mf->GetCacheMajorVersion();
383     unsigned int cacheMinor = mf->GetCacheMinorVersion();
384     unsigned int selfMajor = cmVersion::GetMajorVersion();
385     unsigned int selfMinor = cmVersion::GetMinorVersion();
386     if((this->CMakeInstance->GetIsInTryCompile() ||
387         (selfMajor == cacheMajor && selfMinor == cacheMinor))
388        && !mf->GetDefinition(loadedLang.c_str()))
389       {
390       fpath = rootBin;
391       fpath += "/CMake";
392       fpath += lang;
393       fpath += "Compiler.cmake";
394       if(cmSystemTools::FileExists(fpath.c_str()))
395         {
396         if(!mf->ReadListFile(0,fpath.c_str()))
397           {
398           cmSystemTools::Error("Could not find cmake module file:",
399                                fpath.c_str());
400           }
401         // if this file was found then the language was already determined
402         // to be working
403         needTestLanguage[lang] = false;
404         this->SetLanguageEnabledFlag(lang, mf);
405         needSetLanguageEnabledMaps[lang] = true;
406         // this can only be called after loading CMake(LANG)Compiler.cmake
407         }
408       }
409
410     if(!this->GetLanguageEnabled(lang) )
411       {
412       if (this->CMakeInstance->GetIsInTryCompile())
413         {
414         cmSystemTools::Error("This should not have happen. "
415                              "If you see this message, you are probably "
416                              "using a broken CMakeLists.txt file or a "
417                              "problematic release of CMake");
418         }
419       // if the CMake(LANG)Compiler.cmake file was not found then
420       // load CMakeDetermine(LANG)Compiler.cmake
421       std::string determineCompiler = "CMakeDetermine";
422       determineCompiler += lang;
423       determineCompiler += "Compiler.cmake";
424       std::string determineFile =
425         mf->GetModulesFile(determineCompiler.c_str());
426       if(!mf->ReadListFile(0,determineFile.c_str()))
427         {
428         cmSystemTools::Error("Could not find cmake module file:",
429                              determineFile.c_str());
430         }
431       needTestLanguage[lang] = true;
432       // Some generators like visual studio should not use the env variables
433       // So the global generator can specify that in this variable
434       if(!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV"))
435         {
436         // put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
437         // into the environment, in case user scripts want to run
438         // configure, or sub cmakes
439         std::string compilerName = "CMAKE_";
440         compilerName += lang;
441         compilerName += "_COMPILER";
442         std::string compilerEnv = "CMAKE_";
443         compilerEnv += lang;
444         compilerEnv += "_COMPILER_ENV_VAR";
445         std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str());
446         std::string envVarValue =
447           mf->GetRequiredDefinition(compilerName.c_str());
448         std::string env = envVar;
449         env += "=";
450         env += envVarValue;
451         cmSystemTools::PutEnv(env.c_str());
452         }
453
454       // if determineLanguage was called then load the file it
455       // configures CMake(LANG)Compiler.cmake
456       fpath = rootBin;
457       fpath += "/CMake";
458       fpath += lang;
459       fpath += "Compiler.cmake";
460       if(!mf->ReadListFile(0,fpath.c_str()))
461         {
462         cmSystemTools::Error("Could not find cmake module file:",
463                              fpath.c_str());
464         }
465       this->SetLanguageEnabledFlag(lang, mf);
466       needSetLanguageEnabledMaps[lang] = true;
467       // this can only be called after loading CMake(LANG)Compiler.cmake
468       // the language must be enabled for try compile to work, but we do
469       // not know if it is a working compiler yet so set the test language
470       // flag
471       needTestLanguage[lang] = true;
472       } // end if(!this->GetLanguageEnabled(lang) )
473     }  // end loop over languages
474
475   // **** Load the system specific information if not yet loaded
476   if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
477     {
478     fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
479     if(!mf->ReadListFile(0,fpath.c_str()))
480       {
481       cmSystemTools::Error("Could not find cmake module file:",
482                            fpath.c_str());
483       }
484     }
485   // loop over languages again loading CMake(LANG)Information.cmake
486   //
487   for(std::vector<std::string>::const_iterator l = languages.begin();
488       l != languages.end(); ++l)
489     {
490     const char* lang = l->c_str();
491     if(*l == "NONE")
492       {
493       this->SetLanguageEnabled("NONE", mf);
494       continue;
495       }
496     std::string langLoadedVar = "CMAKE_";
497     langLoadedVar += lang;
498     langLoadedVar += "_INFORMATION_LOADED";
499     if (!mf->GetDefinition(langLoadedVar.c_str()))
500       {
501       fpath = "CMake";
502       fpath +=  lang;
503       fpath += "Information.cmake";
504       std::string informationFile = mf->GetModulesFile(fpath.c_str());
505       if (informationFile.empty())
506         {
507         cmSystemTools::Error("Could not find cmake module file:",
508                              fpath.c_str());
509         }
510       else if(!mf->ReadListFile(0, informationFile.c_str()))
511         {
512         cmSystemTools::Error("Could not process cmake module file:",
513                              informationFile.c_str());
514         }
515       }
516     if (needSetLanguageEnabledMaps[lang])
517       {
518       this->SetLanguageEnabledMaps(lang, mf);
519       }
520     this->LanguagesReady.insert(lang);
521
522     std::string compilerName = "CMAKE_";
523     compilerName += lang;
524     compilerName += "_COMPILER";
525     std::string compilerLangFile = rootBin;
526     compilerLangFile += "/CMake";
527     compilerLangFile += lang;
528     compilerLangFile += "Compiler.cmake";
529     // Test the compiler for the language just setup
530     // (but only if a compiler has been actually found)
531     // At this point we should have enough info for a try compile
532     // which is used in the backward stuff
533     // If the language is untested then test it now with a try compile.
534     if (!mf->IsSet(compilerName.c_str()))
535       {
536       // if the compiler did not work, then remove the
537       // CMake(LANG)Compiler.cmake file so that it will get tested the
538       // next time cmake is run
539       cmSystemTools::RemoveFile(compilerLangFile.c_str());
540       }
541     else if(needTestLanguage[lang])
542       {
543       if (!this->CMakeInstance->GetIsInTryCompile())
544         {
545         std::string testLang = "CMakeTest";
546         testLang += lang;
547         testLang += "Compiler.cmake";
548         std::string ifpath = mf->GetModulesFile(testLang.c_str());
549         if(!mf->ReadListFile(0,ifpath.c_str()))
550           {
551           cmSystemTools::Error("Could not find cmake module file:",
552                                ifpath.c_str());
553           }
554         std::string compilerWorks = "CMAKE_";
555         compilerWorks += lang;
556         compilerWorks += "_COMPILER_WORKS";
557         // if the compiler did not work, then remove the
558         // CMake(LANG)Compiler.cmake file so that it will get tested the
559         // next time cmake is run
560         if(!mf->IsOn(compilerWorks.c_str()))
561           {
562           cmSystemTools::RemoveFile(compilerLangFile.c_str());
563           }
564         else
565           {
566           // load backwards compatibility stuff for C and CXX
567           // for old versions of CMake ListFiles C and CXX had some
568           // backwards compatibility files they have to load
569           // These files have a bunch of try compiles in them so
570           // should only be done
571           if (mf->NeedBackwardsCompatibility(1,4))
572             {
573             if(strcmp(lang, "C") == 0)
574               {
575               ifpath =
576                 mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake");
577               mf->ReadListFile(0,ifpath.c_str());
578               }
579             if(strcmp(lang, "CXX") == 0)
580               {
581               ifpath =
582                 mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake");
583               mf->ReadListFile(0,ifpath.c_str());
584               }
585             }
586           }
587         } // end if in try compile
588       } // end need test language
589     // Store the shared library flags so that we can satisfy CMP0018
590     std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_";
591     sharedLibFlagsVar += lang;
592     sharedLibFlagsVar += "_FLAGS";
593     const char* sharedLibFlags =
594       mf->GetSafeDefinition(sharedLibFlagsVar.c_str());
595     if (sharedLibFlags)
596       {
597       this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags;
598       }
599     } // end for each language
600
601   // Now load files that can override any settings on the platform or for
602   // the project First load the project compatibility file if it is in
603   // cmake
604   std::string projectCompatibility = mf->GetDefinition("CMAKE_ROOT");
605   projectCompatibility += "/Modules/";
606   projectCompatibility += mf->GetSafeDefinition("PROJECT_NAME");
607   projectCompatibility += "Compatibility.cmake";
608   if(cmSystemTools::FileExists(projectCompatibility.c_str()))
609     {
610     mf->ReadListFile(0,projectCompatibility.c_str());
611     }
612 }
613
614 //----------------------------------------------------------------------------
615 const char*
616 cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
617 {
618   if(const char* lang = source.GetLanguage())
619     {
620     if(this->LanguageToOutputExtension.count(lang) > 0)
621       {
622       return this->LanguageToOutputExtension[lang].c_str();
623       }
624     }
625   else
626     {
627     // if no language is found then check to see if it is already an
628     // ouput extension for some language.  In that case it should be ignored
629     // and in this map, so it will not be compiled but will just be used.
630     std::string const& ext = source.GetExtension();
631     if(!ext.empty())
632       {
633       if(this->OutputExtensions.count(ext))
634         {
635         return ext.c_str();
636         }
637       }
638     }
639   return "";
640 }
641
642
643 const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext)
644 {
645   // if there is an extension and it starts with . then move past the
646   // . because the extensions are not stored with a .  in the map
647   if(ext && *ext == '.')
648     {
649     ++ext;
650     }
651   if(this->ExtensionToLanguage.count(ext) > 0)
652     {
653     return this->ExtensionToLanguage[ext].c_str();
654     }
655   return 0;
656 }
657
658 /* SetLanguageEnabled() is now split in two parts:
659 at first the enabled-flag is set. This can then be used in EnabledLanguage()
660 for checking whether the language is already enabled. After setting this
661 flag still the values from the cmake variables have to be copied into the
662 internal maps, this is done in SetLanguageEnabledMaps() which is called
663 after the system- and compiler specific files have been loaded.
664
665 This split was done originally so that compiler-specific configuration
666 files could change the object file extension
667 (CMAKE_<LANG>_OUTPUT_EXTENSION) before the CMake variables were copied
668 to the C++ maps.
669 */
670 void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
671 {
672   this->SetLanguageEnabledFlag(l, mf);
673   this->SetLanguageEnabledMaps(l, mf);
674 }
675
676 void cmGlobalGenerator::SetLanguageEnabledFlag(const char* l, cmMakefile* mf)
677 {
678   this->LanguageEnabled[l] = true;
679
680   // Fill the language-to-extension map with the current variable
681   // settings to make sure it is available for the try_compile()
682   // command source file signature.  In SetLanguageEnabledMaps this
683   // will be done again to account for any compiler- or
684   // platform-specific entries.
685   this->FillExtensionToLanguageMap(l, mf);
686 }
687
688 void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
689 {
690   // use LanguageToLinkerPreference to detect whether this functions has
691   // run before
692   if (this->LanguageToLinkerPreference.find(l) !=
693                                         this->LanguageToLinkerPreference.end())
694     {
695     return;
696     }
697
698   std::string linkerPrefVar = std::string("CMAKE_") +
699     std::string(l) + std::string("_LINKER_PREFERENCE");
700   const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
701   int preference = 0;
702   if(linkerPref)
703     {
704     if (sscanf(linkerPref, "%d", &preference)!=1)
705       {
706       // backward compatibility: before 2.6 LINKER_PREFERENCE
707       // was either "None" or "Prefered", and only the first character was
708       // tested. So if there is a custom language out there and it is
709       // "Prefered", set its preference high
710       if (linkerPref[0]=='P')
711         {
712         preference = 100;
713         }
714       else
715         {
716         preference = 0;
717         }
718       }
719     }
720
721   if (preference < 0)
722     {
723     std::string msg = linkerPrefVar;
724     msg += " is negative, adjusting it to 0";
725     cmSystemTools::Message(msg.c_str(), "Warning");
726     preference = 0;
727     }
728
729   this->LanguageToLinkerPreference[l] = preference;
730
731   std::string outputExtensionVar = std::string("CMAKE_") +
732     std::string(l) + std::string("_OUTPUT_EXTENSION");
733   const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str());
734   if(outputExtension)
735     {
736     this->LanguageToOutputExtension[l] = outputExtension;
737     this->OutputExtensions[outputExtension] = outputExtension;
738     if(outputExtension[0] == '.')
739       {
740       this->OutputExtensions[outputExtension+1] = outputExtension+1;
741       }
742     }
743
744   // The map was originally filled by SetLanguageEnabledFlag, but
745   // since then the compiler- and platform-specific files have been
746   // loaded which might have added more entries.
747   this->FillExtensionToLanguageMap(l, mf);
748
749   std::string ignoreExtensionsVar = std::string("CMAKE_") +
750     std::string(l) + std::string("_IGNORE_EXTENSIONS");
751   std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str());
752   std::vector<std::string> extensionList;
753   cmSystemTools::ExpandListArgument(ignoreExts, extensionList);
754   for(std::vector<std::string>::iterator i = extensionList.begin();
755       i != extensionList.end(); ++i)
756     {
757     this->IgnoreExtensions[*i] = true;
758     }
759
760 }
761
762 void cmGlobalGenerator::FillExtensionToLanguageMap(const char* l,
763                                                    cmMakefile* mf)
764 {
765   std::string extensionsVar = std::string("CMAKE_") +
766     std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS");
767   std::string exts = mf->GetSafeDefinition(extensionsVar.c_str());
768   std::vector<std::string> extensionList;
769   cmSystemTools::ExpandListArgument(exts, extensionList);
770   for(std::vector<std::string>::iterator i = extensionList.begin();
771       i != extensionList.end(); ++i)
772     {
773     this->ExtensionToLanguage[*i] = l;
774     }
775 }
776
777 bool cmGlobalGenerator::IgnoreFile(const char* l)
778 {
779   if(this->GetLanguageFromExtension(l))
780     {
781     return false;
782     }
783   return (this->IgnoreExtensions.count(l) > 0);
784 }
785
786 bool cmGlobalGenerator::GetLanguageEnabled(const char* l) const
787 {
788   return (this->LanguageEnabled.find(l)!= this->LanguageEnabled.end());
789 }
790
791 void cmGlobalGenerator::ClearEnabledLanguages()
792 {
793   this->LanguageEnabled.clear();
794 }
795
796 bool cmGlobalGenerator::IsDependedOn(const char* project,
797                                      cmTarget* targetIn)
798 {
799   // Get all local gens for this project
800   std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
801   // loop over local gens and get the targets for each one
802   for(unsigned int i = 0; i < gens->size(); ++i)
803     {
804     cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets();
805     for (cmTargets::iterator l = targets.begin();
806          l != targets.end(); l++)
807       {
808       cmTarget& target = l->second;
809       TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
810       if(tgtdeps.count(targetIn))
811         {
812         return true;
813         }
814       }
815     }
816   return false;
817 }
818
819 void cmGlobalGenerator::Configure()
820 {
821   this->FirstTimeProgress = 0.0f;
822   this->ClearGeneratorTargets();
823   this->ClearExportSets();
824   // Delete any existing cmLocalGenerators
825   unsigned int i;
826   for (i = 0; i < this->LocalGenerators.size(); ++i)
827     {
828     delete this->LocalGenerators[i];
829     }
830   this->LocalGenerators.clear();
831   this->TargetDependencies.clear();
832   this->TotalTargets.clear();
833   this->LocalGeneratorToTargetMap.clear();
834   this->ProjectMap.clear();
835   this->RuleHashes.clear();
836   this->DirectoryContentMap.clear();
837   this->BinaryDirectories.clear();
838
839   // start with this directory
840   cmLocalGenerator *lg = this->CreateLocalGenerator();
841   this->LocalGenerators.push_back(lg);
842
843   // set the Start directories
844   cmMakefile* mf = lg->GetMakefile();
845   lg->GetMakefile()->SetStartDirectory
846     (this->CMakeInstance->GetStartDirectory());
847   lg->GetMakefile()->SetStartOutputDirectory
848     (this->CMakeInstance->GetStartOutputDirectory());
849   lg->GetMakefile()->MakeStartDirectoriesCurrent();
850
851   this->BinaryDirectories.insert(mf->GetStartOutputDirectory());
852
853   // now do it
854   lg->Configure();
855
856   // update the cache entry for the number of local generators, this is used
857   // for progress
858   char num[100];
859   sprintf(num,"%d",static_cast<int>(this->LocalGenerators.size()));
860   this->GetCMakeInstance()->AddCacheEntry
861     ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
862      "number of local generators", cmCacheManager::INTERNAL);
863
864   // check for link libraries and include directories containing "NOTFOUND"
865   // and for infinite loops
866   this->CheckLocalGenerators();
867
868   // at this point this->LocalGenerators has been filled,
869   // so create the map from project name to vector of local generators
870   this->FillProjectMap();
871
872   if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
873     {
874     const char* msg = "Configuring done";
875     if(cmSystemTools::GetErrorOccuredFlag())
876       {
877       msg = "Configuring incomplete, errors occurred!";
878       }
879     this->CMakeInstance->UpdateProgress(msg, -1);
880     }
881 }
882
883 bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
884 {
885   // If the property is not enabled then okay.
886   if(!this->CMakeInstance
887      ->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
888     {
889     return true;
890     }
891
892   // This generator does not support duplicate custom targets.
893   cmOStringStream e;
894   e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
895     << "global property.  "
896     << "The \"" << this->GetName() << "\" generator does not support "
897     << "duplicate custom targets.  "
898     << "Consider using a Makefiles generator or fix the project to not "
899     << "use duplicat target names.";
900   cmSystemTools::Error(e.str().c_str());
901   return false;
902 }
903
904 void cmGlobalGenerator::Generate()
905 {
906   // Some generators track files replaced during the Generate.
907   // Start with an empty vector:
908   this->FilesReplacedDuringGenerate.clear();
909
910   // Check whether this generator is allowed to run.
911   if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
912     {
913     return;
914     }
915
916   // Check that all targets are valid.
917   if(!this->CheckTargets())
918     {
919     return;
920     }
921
922   // Iterate through all targets and set up automoc for those which have
923   // the AUTOMOC property set
924   this->CreateAutomocTargets();
925
926   // For each existing cmLocalGenerator
927   unsigned int i;
928
929   // Put a copy of each global target in every directory.
930   cmTargets globalTargets;
931   this->CreateDefaultGlobalTargets(&globalTargets);
932   for (i = 0; i < this->LocalGenerators.size(); ++i)
933     {
934     cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
935     cmTargets* targets = &(mf->GetTargets());
936     cmTargets::iterator tit;
937     for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
938       {
939       (*targets)[tit->first] = tit->second;
940       (*targets)[tit->first].SetMakefile(mf);
941       }
942     }
943
944   // Add generator specific helper commands
945   for (i = 0; i < this->LocalGenerators.size(); ++i)
946     {
947     this->LocalGenerators[i]->AddHelperCommands();
948     }
949
950   // Trace the dependencies, after that no custom commands should be added
951   // because their dependencies might not be handled correctly
952   for (i = 0; i < this->LocalGenerators.size(); ++i)
953     {
954     this->LocalGenerators[i]->TraceDependencies();
955     }
956
957   // Compute the manifest of main targets generated.
958   for (i = 0; i < this->LocalGenerators.size(); ++i)
959     {
960     this->LocalGenerators[i]->GenerateTargetManifest();
961     }
962
963   // Create per-target generator information.
964   this->CreateGeneratorTargets();
965
966   // Compute the inter-target dependencies.
967   if(!this->ComputeTargetDepends())
968     {
969     return;
970     }
971
972   // Create a map from local generator to the complete set of targets
973   // it builds by default.
974   this->FillLocalGeneratorToTargetMap();
975
976   // Generate project files
977   for (i = 0; i < this->LocalGenerators.size(); ++i)
978     {
979     this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
980     this->LocalGenerators[i]->Generate();
981     this->LocalGenerators[i]->GenerateInstallRules();
982     this->LocalGenerators[i]->GenerateTestFiles();
983     this->CMakeInstance->UpdateProgress("Generating",
984       (static_cast<float>(i)+1.0f)/
985        static_cast<float>(this->LocalGenerators.size()));
986     }
987   this->SetCurrentLocalGenerator(0);
988
989   // Update rule hashes.
990   this->CheckRuleHashes();
991
992   this->WriteSummary();
993
994   if (this->ExtraGenerator != 0)
995     {
996     this->ExtraGenerator->Generate();
997     }
998
999   this->CMakeInstance->UpdateProgress("Generating done", -1);
1000 }
1001
1002 //----------------------------------------------------------------------------
1003 bool cmGlobalGenerator::ComputeTargetDepends()
1004 {
1005   cmComputeTargetDepends ctd(this);
1006   if(!ctd.Compute())
1007     {
1008     return false;
1009     }
1010   std::vector<cmTarget*> const& targets = ctd.GetTargets();
1011   for(std::vector<cmTarget*>::const_iterator ti = targets.begin();
1012       ti != targets.end(); ++ti)
1013     {
1014     ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
1015     }
1016   return true;
1017 }
1018
1019 //----------------------------------------------------------------------------
1020 bool cmGlobalGenerator::CheckTargets()
1021 {
1022   // Make sure all targets can find their source files.
1023   for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
1024     {
1025     cmTargets& targets =
1026       this->LocalGenerators[i]->GetMakefile()->GetTargets();
1027     for(cmTargets::iterator ti = targets.begin();
1028         ti != targets.end(); ++ti)
1029       {
1030       cmTarget& target = ti->second;
1031       if(target.GetType() == cmTarget::EXECUTABLE ||
1032          target.GetType() == cmTarget::STATIC_LIBRARY ||
1033          target.GetType() == cmTarget::SHARED_LIBRARY ||
1034          target.GetType() == cmTarget::MODULE_LIBRARY ||
1035          target.GetType() == cmTarget::UTILITY)
1036         {
1037         if(!target.FindSourceFiles())
1038           {
1039           return false;
1040           }
1041         }
1042       }
1043     }
1044   return true;
1045 }
1046
1047 //----------------------------------------------------------------------------
1048 void cmGlobalGenerator::CreateAutomocTargets()
1049 {
1050 #ifdef CMAKE_BUILD_WITH_CMAKE
1051   for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
1052     {
1053     cmTargets& targets =
1054       this->LocalGenerators[i]->GetMakefile()->GetTargets();
1055     for(cmTargets::iterator ti = targets.begin();
1056         ti != targets.end(); ++ti)
1057       {
1058       cmTarget& target = ti->second;
1059       if(target.GetType() == cmTarget::EXECUTABLE ||
1060          target.GetType() == cmTarget::STATIC_LIBRARY ||
1061          target.GetType() == cmTarget::SHARED_LIBRARY ||
1062          target.GetType() == cmTarget::MODULE_LIBRARY)
1063         {
1064         if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
1065           {
1066           cmQtAutomoc automoc;
1067           automoc.SetupAutomocTarget(&target);
1068           }
1069         }
1070       }
1071     }
1072 #endif
1073 }
1074
1075 //----------------------------------------------------------------------------
1076 void cmGlobalGenerator::CreateGeneratorTargets()
1077 {
1078   // Construct per-target generator information.
1079   for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
1080     {
1081     cmTargets& targets =
1082       this->LocalGenerators[i]->GetMakefile()->GetTargets();
1083     for(cmTargets::iterator ti = targets.begin();
1084         ti != targets.end(); ++ti)
1085       {
1086       cmTarget* t = &ti->second;
1087       cmGeneratorTarget* gt = new cmGeneratorTarget(t);
1088       this->GeneratorTargets[t] = gt;
1089       this->ComputeTargetObjects(gt);
1090       }
1091     }
1092 }
1093
1094 //----------------------------------------------------------------------------
1095 void cmGlobalGenerator::ClearGeneratorTargets()
1096 {
1097   for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin();
1098       i != this->GeneratorTargets.end(); ++i)
1099     {
1100     delete i->second;
1101     }
1102   this->GeneratorTargets.clear();
1103 }
1104
1105 //----------------------------------------------------------------------------
1106 cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const
1107 {
1108   GeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t);
1109   if(ti == this->GeneratorTargets.end())
1110     {
1111     this->CMakeInstance->IssueMessage(
1112       cmake::INTERNAL_ERROR, "Missing cmGeneratorTarget instance!",
1113       cmListFileBacktrace());
1114     return 0;
1115     }
1116   return ti->second;
1117 }
1118
1119 //----------------------------------------------------------------------------
1120 void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const
1121 {
1122   // Implemented in generator subclasses that need this.
1123 }
1124
1125 void cmGlobalGenerator::CheckLocalGenerators()
1126 {
1127   std::map<cmStdString, cmStdString> notFoundMap;
1128 //  std::set<cmStdString> notFoundMap;
1129   // after it is all done do a ConfigureFinalPass
1130   cmCacheManager* manager = 0;
1131   for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
1132     {
1133     manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager();
1134     this->LocalGenerators[i]->ConfigureFinalPass();
1135     cmTargets & targets =
1136       this->LocalGenerators[i]->GetMakefile()->GetTargets();
1137     for (cmTargets::iterator l = targets.begin();
1138          l != targets.end(); l++)
1139       {
1140       const cmTarget::LinkLibraryVectorType& libs =
1141         l->second.GetOriginalLinkLibraries();
1142       for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin();
1143           lib != libs.end(); ++lib)
1144         {
1145         if(lib->first.size() > 9 &&
1146            cmSystemTools::IsNOTFOUND(lib->first.c_str()))
1147           {
1148           std::string varName = lib->first.substr(0, lib->first.size()-9);
1149           cmCacheManager::CacheIterator it =
1150             manager->GetCacheIterator(varName.c_str());
1151           if(it.GetPropertyAsBool("ADVANCED"))
1152             {
1153             varName += " (ADVANCED)";
1154             }
1155           std::string text = notFoundMap[varName];
1156           text += "\n    linked by target \"";
1157           text += l->second.GetName();
1158           text += "\" in directory ";
1159           text+=this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory();
1160           notFoundMap[varName] = text;
1161           }
1162         }
1163       std::vector<std::string> incs;
1164       this->LocalGenerators[i]->GetIncludeDirectories(incs, &l->second);
1165
1166       for( std::vector<std::string>::const_iterator incDir = incs.begin();
1167             incDir != incs.end(); ++incDir)
1168         {
1169         if(incDir->size() > 9 &&
1170             cmSystemTools::IsNOTFOUND(incDir->c_str()))
1171           {
1172           std::string varName = incDir->substr(0, incDir->size()-9);
1173           cmCacheManager::CacheIterator it =
1174             manager->GetCacheIterator(varName.c_str());
1175           if(it.GetPropertyAsBool("ADVANCED"))
1176             {
1177             varName += " (ADVANCED)";
1178             }
1179           std::string text = notFoundMap[varName];
1180           text += "\n   used as include directory in directory ";
1181           text += this->LocalGenerators[i]
1182                       ->GetMakefile()->GetCurrentDirectory();
1183           notFoundMap[varName] = text;
1184           }
1185         }
1186       }
1187     this->CMakeInstance->UpdateProgress
1188       ("Configuring", 0.9f+0.1f*(static_cast<float>(i)+1.0f)/
1189         static_cast<float>(this->LocalGenerators.size()));
1190     }
1191
1192   if(notFoundMap.size())
1193     {
1194     std::string notFoundVars;
1195     for(std::map<cmStdString, cmStdString>::const_iterator
1196         ii = notFoundMap.begin();
1197         ii != notFoundMap.end();
1198         ++ii)
1199       {
1200       notFoundVars += ii->first;
1201       notFoundVars += ii->second;
1202       notFoundVars += "\n";
1203       }
1204     cmSystemTools::Error("The following variables are used in this project, "
1205                          "but they are set to NOTFOUND.\n"
1206                          "Please set them or make sure they are set and "
1207                          "tested correctly in the CMake files:\n",
1208                          notFoundVars.c_str());
1209     }
1210 }
1211
1212 int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
1213                                   const char *projectName,
1214                                   const char *target, bool fast,
1215                                   std::string *output, cmMakefile *mf)
1216 {
1217   // if this is not set, then this is a first time configure
1218   // and there is a good chance that the try compile stuff will
1219   // take the bulk of the time, so try and guess some progress
1220   // by getting closer and closer to 100 without actually getting there.
1221   if (!this->CMakeInstance->GetCacheManager()->GetCacheValue
1222       ("CMAKE_NUMBER_OF_LOCAL_GENERATORS"))
1223     {
1224     // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
1225     // we are in the first time progress and we have no
1226     // idea how long it will be.  So, just move 1/10th of the way
1227     // there each time, and don't go over 95%
1228     this->FirstTimeProgress += ((1.0f - this->FirstTimeProgress) /30.0f);
1229     if(this->FirstTimeProgress > 0.95f)
1230       {
1231       this->FirstTimeProgress = 0.95f;
1232       }
1233     this->CMakeInstance->UpdateProgress("Configuring",
1234                                         this->FirstTimeProgress);
1235     }
1236
1237   std::string makeCommand = this->CMakeInstance->
1238     GetCacheManager()->GetCacheValue("CMAKE_MAKE_PROGRAM");
1239   if(makeCommand.size() == 0)
1240     {
1241     cmSystemTools::Error(
1242       "Generator cannot find the appropriate make command.");
1243     return 1;
1244     }
1245
1246   std::string newTarget;
1247   if (target && strlen(target))
1248     {
1249     newTarget += target;
1250 #if 0
1251 #if defined(_WIN32) || defined(__CYGWIN__)
1252     std::string tmp = target;
1253     // if the target does not already end in . something
1254     // then assume .exe
1255     if(tmp.size() < 4 || tmp[tmp.size()-4] != '.')
1256       {
1257       newTarget += ".exe";
1258       }
1259 #endif // WIN32
1260 #endif
1261     }
1262   const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
1263   return this->Build(srcdir,bindir,projectName,
1264                      newTarget.c_str(),
1265                      output,makeCommand.c_str(),config,false,fast,
1266                      this->TryCompileTimeout);
1267 }
1268
1269 std::string cmGlobalGenerator
1270 ::GenerateBuildCommand(const char* makeProgram, const char *projectName,
1271                        const char* additionalOptions, const char *targetName,
1272                        const char* config, bool ignoreErrors, bool)
1273 {
1274   // Project name and config are not used yet.
1275   (void)projectName;
1276   (void)config;
1277
1278   std::string makeCommand =
1279     cmSystemTools::ConvertToUnixOutputPath(makeProgram);
1280
1281   // Since we have full control over the invocation of nmake, let us
1282   // make it quiet.
1283   if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
1284     {
1285     makeCommand += " /NOLOGO ";
1286     }
1287   if ( ignoreErrors )
1288     {
1289     makeCommand += " -i";
1290     }
1291   if ( additionalOptions )
1292     {
1293     makeCommand += " ";
1294     makeCommand += additionalOptions;
1295     }
1296   if ( targetName )
1297     {
1298     makeCommand += " ";
1299     makeCommand += targetName;
1300     }
1301   return makeCommand;
1302 }
1303
1304 int cmGlobalGenerator::Build(
1305   const char *, const char *bindir,
1306   const char *projectName, const char *target,
1307   std::string *output,
1308   const char *makeCommandCSTR,
1309   const char *config,
1310   bool clean, bool fast,
1311   double timeout,
1312   cmSystemTools::OutputOption outputflag,
1313   const char* extraOptions,
1314   std::vector<std::string> const& nativeOptions)
1315 {
1316   /**
1317    * Run an executable command and put the stdout in output.
1318    */
1319   std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
1320   cmSystemTools::ChangeDirectory(bindir);
1321   if(output)
1322     {
1323     *output += "Change Dir: ";
1324     *output += bindir;
1325     *output += "\n";
1326     }
1327
1328   int retVal;
1329   bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
1330   cmSystemTools::SetRunCommandHideConsole(true);
1331   std::string outputBuffer;
1332   std::string* outputPtr = 0;
1333   if(output)
1334     {
1335     outputPtr = &outputBuffer;
1336     }
1337
1338   // should we do a clean first?
1339   if (clean)
1340     {
1341     std::string cleanCommand =
1342       this->GenerateBuildCommand(makeCommandCSTR, projectName,
1343       0, "clean", config, false, fast);
1344     if(output)
1345       {
1346       *output += "\nRun Clean Command:";
1347       *output += cleanCommand;
1348       *output += "\n";
1349       }
1350
1351     if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr,
1352                                          &retVal, 0, outputflag, timeout))
1353       {
1354       cmSystemTools::SetRunCommandHideConsole(hideconsole);
1355       cmSystemTools::Error("Generator: execution of make clean failed.");
1356       if (output)
1357         {
1358         *output += *outputPtr;
1359         *output += "\nGenerator: execution of make clean failed.\n";
1360         }
1361
1362       // return to the original directory
1363       cmSystemTools::ChangeDirectory(cwd.c_str());
1364       return 1;
1365       }
1366     if (output)
1367       {
1368       *output += *outputPtr;
1369       }
1370     }
1371
1372   // now build
1373   std::string makeCommand =
1374     this->GenerateBuildCommand(makeCommandCSTR, projectName,
1375                                extraOptions, target,
1376                                config, false, fast);
1377   if(output)
1378     {
1379     *output += "\nRun Build Command:";
1380     *output += makeCommand;
1381     *output += "\n";
1382     }
1383
1384   std::vector<cmStdString> command =
1385     cmSystemTools::ParseArguments(makeCommand.c_str());
1386   for(std::vector<std::string>::const_iterator ni = nativeOptions.begin();
1387       ni != nativeOptions.end(); ++ni)
1388     {
1389     command.push_back(*ni);
1390     }
1391
1392   if (!cmSystemTools::RunSingleCommand(command, outputPtr,
1393                                        &retVal, 0, outputflag, timeout))
1394     {
1395     cmSystemTools::SetRunCommandHideConsole(hideconsole);
1396     cmSystemTools::Error
1397       ("Generator: execution of make failed. Make command was: ",
1398        makeCommand.c_str());
1399     if (output)
1400       {
1401       *output += *outputPtr;
1402       *output += "\nGenerator: execution of make failed. Make command was: "
1403         + makeCommand + "\n";
1404       }
1405
1406     // return to the original directory
1407     cmSystemTools::ChangeDirectory(cwd.c_str());
1408     return 1;
1409     }
1410   if (output)
1411     {
1412     *output += *outputPtr;
1413     }
1414   cmSystemTools::SetRunCommandHideConsole(hideconsole);
1415
1416   // The SGI MipsPro 7.3 compiler does not return an error code when
1417   // the source has a #error in it!  This is a work-around for such
1418   // compilers.
1419   if((retVal == 0) && (output->find("#error") != std::string::npos))
1420     {
1421     retVal = 1;
1422     }
1423
1424   cmSystemTools::ChangeDirectory(cwd.c_str());
1425   return retVal;
1426 }
1427
1428 void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
1429 {
1430   this->LocalGenerators.push_back(lg);
1431
1432   // update progress
1433   // estimate how many lg there will be
1434   const char *numGenC =
1435     this->CMakeInstance->GetCacheManager()->GetCacheValue
1436     ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
1437
1438   if (!numGenC)
1439     {
1440     // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
1441     // we are in the first time progress and we have no
1442     // idea how long it will be.  So, just move half way
1443     // there each time, and don't go over 95%
1444     this->FirstTimeProgress += ((1.0f - this->FirstTimeProgress) /30.0f);
1445     if(this->FirstTimeProgress > 0.95f)
1446       {
1447       this->FirstTimeProgress = 0.95f;
1448       }
1449     this->CMakeInstance->UpdateProgress("Configuring",
1450                                         this->FirstTimeProgress);
1451     return;
1452     }
1453
1454   int numGen = atoi(numGenC);
1455   float prog = 0.9f*static_cast<float>(this->LocalGenerators.size())/
1456     static_cast<float>(numGen);
1457   if (prog > 0.9f)
1458     {
1459     prog = 0.9f;
1460     }
1461   this->CMakeInstance->UpdateProgress("Configuring", prog);
1462 }
1463
1464 void cmGlobalGenerator::AddInstallComponent(const char* component)
1465 {
1466   if(component && *component)
1467     {
1468     this->InstallComponents.insert(component);
1469     }
1470 }
1471
1472 void cmGlobalGenerator::AddTargetToExports(const char* exportSetName,
1473                                            cmTarget* target,
1474                                            cmInstallTargetGenerator* archive,
1475                                            cmInstallTargetGenerator* runTime,
1476                                            cmInstallTargetGenerator* library,
1477                                            cmInstallTargetGenerator* framework,
1478                                            cmInstallTargetGenerator* bundle,
1479                                            cmInstallFilesGenerator* headers)
1480 {
1481   if ((exportSetName) && (*exportSetName) && (target))
1482     {
1483     cmTargetExport* te = new cmTargetExport(target, archive, runTime, library,
1484                                             framework, bundle, headers);
1485     this->ExportSets[exportSetName].push_back(te);
1486     }
1487 }
1488
1489 //----------------------------------------------------------------------------
1490 void cmGlobalGenerator::ClearExportSets()
1491 {
1492   for(std::map<cmStdString, std::vector<cmTargetExport*> >::iterator
1493         setIt = this->ExportSets.begin();
1494       setIt != this->ExportSets.end(); ++setIt)
1495     {
1496     for(unsigned int i = 0; i < setIt->second.size(); ++i)
1497       {
1498       delete setIt->second[i];
1499       }
1500     }
1501   this->ExportSets.clear();
1502 }
1503
1504 const std::vector<cmTargetExport*>* cmGlobalGenerator::GetExportSet(
1505                                                         const char* name) const
1506 {
1507   std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator
1508                                      exportSetIt = this->ExportSets.find(name);
1509   if (exportSetIt != this->ExportSets.end())
1510     {
1511     return &exportSetIt->second;
1512     }
1513
1514   return 0;
1515 }
1516
1517
1518 void cmGlobalGenerator::EnableInstallTarget()
1519 {
1520   this->InstallTargetEnabled = true;
1521 }
1522
1523 cmLocalGenerator *cmGlobalGenerator::CreateLocalGenerator()
1524 {
1525   cmLocalGenerator *lg = new cmLocalGenerator;
1526   lg->SetGlobalGenerator(this);
1527   return lg;
1528 }
1529
1530 void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
1531                                                      cmMakefile* mf)
1532 {
1533   this->SetConfiguredFilesPath(gen);
1534   this->TryCompileOuterMakefile = mf;
1535   const char* make =
1536     gen->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
1537   this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", make,
1538                                           "make program",
1539                                           cmCacheManager::FILEPATH);
1540   // copy the enabled languages
1541   this->LanguageEnabled = gen->LanguageEnabled;
1542   this->LanguagesReady = gen->LanguagesReady;
1543   this->ExtensionToLanguage = gen->ExtensionToLanguage;
1544   this->IgnoreExtensions = gen->IgnoreExtensions;
1545   this->LanguageToOutputExtension = gen->LanguageToOutputExtension;
1546   this->LanguageToLinkerPreference = gen->LanguageToLinkerPreference;
1547   this->OutputExtensions = gen->OutputExtensions;
1548 }
1549
1550 //----------------------------------------------------------------------------
1551 void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
1552 {
1553   if(!gen->ConfiguredFilesPath.empty())
1554     {
1555     this->ConfiguredFilesPath = gen->ConfiguredFilesPath;
1556     }
1557   else
1558     {
1559     this->ConfiguredFilesPath = gen->CMakeInstance->GetHomeOutputDirectory();
1560     this->ConfiguredFilesPath += cmake::GetCMakeFilesDirectory();
1561     }
1562 }
1563
1564 //----------------------------------------------------------------------------
1565 void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
1566 {
1567   entry.Name = this->GetName();
1568   entry.Brief = "";
1569   entry.Full = "";
1570 }
1571
1572 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
1573                                    cmLocalGenerator* gen)
1574 {
1575   if(!gen || gen == root)
1576     {
1577     // No directory excludes itself.
1578     return false;
1579     }
1580
1581   if(gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
1582     {
1583     // This directory is excluded from its parent.
1584     return true;
1585     }
1586
1587   // This directory is included in its parent.  Check whether the
1588   // parent is excluded.
1589   return this->IsExcluded(root, gen->GetParent());
1590 }
1591
1592 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
1593                                    cmTarget& target)
1594 {
1595   if(target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
1596     {
1597     // This target is excluded from its directory.
1598     return true;
1599     }
1600   else
1601     {
1602     // This target is included in its directory.  Check whether the
1603     // directory is excluded.
1604     return this->IsExcluded(root, target.GetMakefile()->GetLocalGenerator());
1605     }
1606 }
1607
1608 void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
1609 {
1610   for(std::map<cmStdString, bool>::iterator i =
1611         this->LanguageEnabled.begin(); i != this->LanguageEnabled.end(); ++i)
1612     {
1613     lang.push_back(i->first);
1614     }
1615 }
1616
1617 int cmGlobalGenerator::GetLinkerPreference(const char* lang)
1618 {
1619   std::map<cmStdString, int>::const_iterator it =
1620                                    this->LanguageToLinkerPreference.find(lang);
1621   if (it != this->LanguageToLinkerPreference.end())
1622     {
1623     return it->second;
1624     }
1625   return 0;
1626 }
1627
1628 void cmGlobalGenerator::FillProjectMap()
1629 {
1630   this->ProjectMap.clear(); // make sure we start with a clean map
1631   unsigned int i;
1632   for(i = 0; i < this->LocalGenerators.size(); ++i)
1633     {
1634     // for each local generator add all projects
1635     cmLocalGenerator *lg = this->LocalGenerators[i];
1636     std::string name;
1637     do
1638       {
1639       if (name != lg->GetMakefile()->GetProjectName())
1640         {
1641         name = lg->GetMakefile()->GetProjectName();
1642         this->ProjectMap[name].push_back(this->LocalGenerators[i]);
1643         }
1644       lg = lg->GetParent();
1645       }
1646     while (lg);
1647     }
1648 }
1649
1650
1651 // Build a map that contains a the set of targets used by each local
1652 // generator directory level.
1653 void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
1654 {
1655   this->LocalGeneratorToTargetMap.clear();
1656   // Loop over all targets in all local generators.
1657   for(std::vector<cmLocalGenerator*>::const_iterator
1658         lgi = this->LocalGenerators.begin();
1659       lgi != this->LocalGenerators.end(); ++lgi)
1660     {
1661     cmLocalGenerator* lg = *lgi;
1662     cmMakefile* mf = lg->GetMakefile();
1663     cmTargets& targets = mf->GetTargets();
1664     for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
1665       {
1666       cmTarget& target = t->second;
1667
1668       // Consider the directory containing the target and all its
1669       // parents until something excludes the target.
1670       for(cmLocalGenerator* clg = lg; clg && !this->IsExcluded(clg, target);
1671           clg = clg->GetParent())
1672         {
1673         // This local generator includes the target.
1674         std::set<cmTarget*>& targetSet =
1675           this->LocalGeneratorToTargetMap[clg];
1676         targetSet.insert(&target);
1677
1678         // Add dependencies of the included target.  An excluded
1679         // target may still be included if it is a dependency of a
1680         // non-excluded target.
1681         TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
1682         for(TargetDependSet::const_iterator ti = tgtdeps.begin();
1683             ti != tgtdeps.end(); ++ti)
1684           {
1685           targetSet.insert(*ti);
1686           }
1687         }
1688       }
1689     }
1690 }
1691
1692
1693 ///! Find a local generator by its startdirectory
1694 cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
1695 {
1696   std::vector<cmLocalGenerator*>* gens = &this->LocalGenerators;
1697   for(unsigned int i = 0; i < gens->size(); ++i)
1698     {
1699     std::string sd = (*gens)[i]->GetMakefile()->GetStartDirectory();
1700     if (sd == start_dir)
1701       {
1702       return (*gens)[i];
1703       }
1704     }
1705   return 0;
1706 }
1707
1708
1709 //----------------------------------------------------------------------------
1710 cmTarget*
1711 cmGlobalGenerator::FindTarget(const char* project, const char* name)
1712 {
1713   // if project specific
1714   if(project)
1715     {
1716     std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
1717     for(unsigned int i = 0; i < gens->size(); ++i)
1718       {
1719       cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name);
1720       if(ret)
1721         {
1722         return ret;
1723         }
1724       }
1725     }
1726   // if all projects/directories
1727   else
1728     {
1729     std::map<cmStdString,cmTarget *>::iterator i =
1730       this->TotalTargets.find ( name );
1731     if ( i != this->TotalTargets.end() )
1732       {
1733       return i->second;
1734       }
1735     i = this->ImportedTargets.find(name);
1736     if ( i != this->ImportedTargets.end() )
1737       {
1738       return i->second;
1739       }
1740     }
1741   return 0;
1742 }
1743
1744 //----------------------------------------------------------------------------
1745 bool cmGlobalGenerator::NameResolvesToFramework(const std::string& libname)
1746 {
1747   if(cmSystemTools::IsPathToFramework(libname.c_str()))
1748     {
1749     return true;
1750     }
1751
1752   if(cmTarget* tgt = this->FindTarget(0, libname.c_str()))
1753     {
1754     if(tgt->IsFrameworkOnApple())
1755        {
1756        return true;
1757        }
1758     }
1759
1760   return false;
1761 }
1762
1763 //----------------------------------------------------------------------------
1764 inline std::string removeQuotes(const std::string& s)
1765 {
1766   if(s[0] == '\"' && s[s.size()-1] == '\"')
1767     {
1768     return s.substr(1, s.size()-2);
1769     }
1770   return s;
1771 }
1772
1773 void cmGlobalGenerator::SetCMakeInstance(cmake* cm)
1774 {
1775   // Store a pointer to the cmake object instance.
1776   this->CMakeInstance = cm;
1777 }
1778
1779 void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
1780 {
1781   cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
1782   const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
1783   const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
1784
1785   // CPack
1786   std::string workingDir =  mf->GetStartOutputDirectory();
1787   cmCustomCommandLines cpackCommandLines;
1788   std::vector<std::string> depends;
1789   cmCustomCommandLine singleLine;
1790   singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
1791   if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
1792     {
1793     singleLine.push_back("-C");
1794     singleLine.push_back(cmakeCfgIntDir);
1795     }
1796   singleLine.push_back("--config");
1797   std::string configFile = mf->GetStartOutputDirectory();;
1798   configFile += "/CPackConfig.cmake";
1799   std::string relConfigFile = "./CPackConfig.cmake";
1800   singleLine.push_back(relConfigFile);
1801   cpackCommandLines.push_back(singleLine);
1802   if ( this->GetPreinstallTargetName() )
1803     {
1804     depends.push_back(this->GetPreinstallTargetName());
1805     }
1806   else
1807     {
1808     const char* noPackageAll =
1809       mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY");
1810     if(!noPackageAll || cmSystemTools::IsOff(noPackageAll))
1811       {
1812       depends.push_back(this->GetAllTargetName());
1813       }
1814     }
1815   if(cmSystemTools::FileExists(configFile.c_str()))
1816     {
1817     (*targets)[this->GetPackageTargetName()]
1818       = this->CreateGlobalTarget(this->GetPackageTargetName(),
1819                                  "Run CPack packaging tool...",
1820                                  &cpackCommandLines, depends,
1821                                  workingDir.c_str());
1822     }
1823   // CPack source
1824   const char* packageSourceTargetName = this->GetPackageSourceTargetName();
1825   if ( packageSourceTargetName )
1826     {
1827     cpackCommandLines.erase(cpackCommandLines.begin(),
1828                             cpackCommandLines.end());
1829     singleLine.erase(singleLine.begin(), singleLine.end());
1830     depends.erase(depends.begin(), depends.end());
1831     singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
1832     singleLine.push_back("--config");
1833     configFile = mf->GetStartOutputDirectory();;
1834     configFile += "/CPackSourceConfig.cmake";
1835     relConfigFile = "./CPackSourceConfig.cmake";
1836     singleLine.push_back(relConfigFile);
1837     if(cmSystemTools::FileExists(configFile.c_str()))
1838       {
1839       singleLine.push_back(configFile);
1840       cpackCommandLines.push_back(singleLine);
1841       (*targets)[packageSourceTargetName]
1842         = this->CreateGlobalTarget(packageSourceTargetName,
1843                                    "Run CPack packaging tool for source...",
1844                                    &cpackCommandLines, depends,
1845                                    workingDir.c_str()
1846                                    );
1847       }
1848     }
1849
1850   // Test
1851   if(mf->IsOn("CMAKE_TESTING_ENABLED"))
1852     {
1853     cpackCommandLines.erase(cpackCommandLines.begin(),
1854                             cpackCommandLines.end());
1855     singleLine.erase(singleLine.begin(), singleLine.end());
1856     depends.erase(depends.begin(), depends.end());
1857     singleLine.push_back(this->GetCMakeInstance()->GetCTestCommand());
1858     singleLine.push_back("--force-new-ctest-process");
1859     if(cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.')
1860       {
1861       singleLine.push_back("-C");
1862       singleLine.push_back(cmakeCfgIntDir);
1863       }
1864     else // TODO: This is a hack. Should be something to do with the generator
1865       {
1866       singleLine.push_back("$(ARGS)");
1867       }
1868     cpackCommandLines.push_back(singleLine);
1869     (*targets)[this->GetTestTargetName()]
1870       = this->CreateGlobalTarget(this->GetTestTargetName(),
1871         "Running tests...", &cpackCommandLines, depends, 0);
1872     }
1873
1874   //Edit Cache
1875   const char* editCacheTargetName = this->GetEditCacheTargetName();
1876   if ( editCacheTargetName )
1877     {
1878     cpackCommandLines.erase(cpackCommandLines.begin(),
1879                             cpackCommandLines.end());
1880     singleLine.erase(singleLine.begin(), singleLine.end());
1881     depends.erase(depends.begin(), depends.end());
1882
1883     // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined.
1884     // Otherwise default to the interactive command-line interface.
1885     if(mf->GetDefinition("CMAKE_EDIT_COMMAND"))
1886       {
1887       singleLine.push_back(mf->GetDefinition("CMAKE_EDIT_COMMAND"));
1888       singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
1889       singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
1890       cpackCommandLines.push_back(singleLine);
1891       (*targets)[editCacheTargetName] =
1892         this->CreateGlobalTarget(
1893           editCacheTargetName, "Running CMake cache editor...",
1894           &cpackCommandLines, depends, 0);
1895       }
1896     else
1897       {
1898       singleLine.push_back(cmakeCommand);
1899       singleLine.push_back("-i");
1900       singleLine.push_back(".");
1901       cpackCommandLines.push_back(singleLine);
1902       (*targets)[editCacheTargetName] =
1903         this->CreateGlobalTarget(
1904           editCacheTargetName,
1905           "Running interactive CMake command-line interface...",
1906           &cpackCommandLines, depends, 0);
1907       }
1908     }
1909
1910   //Rebuild Cache
1911   const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
1912   if ( rebuildCacheTargetName )
1913     {
1914     cpackCommandLines.erase(cpackCommandLines.begin(),
1915                             cpackCommandLines.end());
1916     singleLine.erase(singleLine.begin(), singleLine.end());
1917     depends.erase(depends.begin(), depends.end());
1918     singleLine.push_back(cmakeCommand);
1919     singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
1920     singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
1921     cpackCommandLines.push_back(singleLine);
1922     (*targets)[rebuildCacheTargetName] =
1923       this->CreateGlobalTarget(
1924         rebuildCacheTargetName, "Running CMake to regenerate build system...",
1925         &cpackCommandLines, depends, 0);
1926     }
1927
1928   //Install
1929   if(this->InstallTargetEnabled)
1930     {
1931     if(!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.')
1932       {
1933       std::set<cmStdString>* componentsSet = &this->InstallComponents;
1934       cpackCommandLines.erase(cpackCommandLines.begin(),
1935         cpackCommandLines.end());
1936       depends.erase(depends.begin(), depends.end());
1937       cmOStringStream ostr;
1938       if ( componentsSet->size() > 0 )
1939         {
1940         ostr << "Available install components are:";
1941         std::set<cmStdString>::iterator it;
1942         for (
1943           it = componentsSet->begin();
1944           it != componentsSet->end();
1945           ++ it )
1946           {
1947           ostr << " \"" << it->c_str() << "\"";
1948           }
1949         }
1950       else
1951         {
1952         ostr << "Only default component available";
1953         }
1954       singleLine.push_back(ostr.str().c_str());
1955       (*targets)["list_install_components"]
1956         = this->CreateGlobalTarget("list_install_components",
1957           ostr.str().c_str(),
1958           &cpackCommandLines, depends, 0);
1959       }
1960     std::string cmd = cmakeCommand;
1961     cpackCommandLines.erase(cpackCommandLines.begin(),
1962       cpackCommandLines.end());
1963     singleLine.erase(singleLine.begin(), singleLine.end());
1964     depends.erase(depends.begin(), depends.end());
1965     if ( this->GetPreinstallTargetName() )
1966       {
1967       depends.push_back(this->GetPreinstallTargetName());
1968       }
1969     else
1970       {
1971       const char* noall =
1972         mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
1973       if(!noall || cmSystemTools::IsOff(noall))
1974         {
1975         depends.push_back(this->GetAllTargetName());
1976         }
1977       }
1978     if(mf->GetDefinition("CMake_BINARY_DIR"))
1979       {
1980       // We are building CMake itself.  We cannot use the original
1981       // executable to install over itself.  The generator will
1982       // automatically convert this name to the build-time location.
1983       cmd = "cmake";
1984       }
1985     singleLine.push_back(cmd.c_str());
1986     if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
1987       {
1988       std::string cfgArg = "-DBUILD_TYPE=";
1989       cfgArg += mf->GetDefinition("CMAKE_CFG_INTDIR");
1990       singleLine.push_back(cfgArg);
1991       }
1992     singleLine.push_back("-P");
1993     singleLine.push_back("cmake_install.cmake");
1994     cpackCommandLines.push_back(singleLine);
1995     (*targets)[this->GetInstallTargetName()] =
1996       this->CreateGlobalTarget(
1997         this->GetInstallTargetName(), "Install the project...",
1998         &cpackCommandLines, depends, 0);
1999
2000     // install_local
2001     if(const char* install_local = this->GetInstallLocalTargetName())
2002       {
2003       cmCustomCommandLine localCmdLine = singleLine;
2004
2005       localCmdLine.insert(localCmdLine.begin()+1,
2006                                                "-DCMAKE_INSTALL_LOCAL_ONLY=1");
2007       cpackCommandLines.erase(cpackCommandLines.begin(),
2008                                                       cpackCommandLines.end());
2009       cpackCommandLines.push_back(localCmdLine);
2010
2011       (*targets)[install_local] =
2012         this->CreateGlobalTarget(
2013           install_local, "Installing only the local directory...",
2014           &cpackCommandLines, depends, 0);
2015       }
2016
2017     // install_strip
2018     const char* install_strip = this->GetInstallStripTargetName();
2019     if((install_strip !=0) && (mf->IsSet("CMAKE_STRIP")))
2020       {
2021       cmCustomCommandLine stripCmdLine = singleLine;
2022
2023       stripCmdLine.insert(stripCmdLine.begin()+1,"-DCMAKE_INSTALL_DO_STRIP=1");
2024       cpackCommandLines.erase(cpackCommandLines.begin(),
2025         cpackCommandLines.end());
2026       cpackCommandLines.push_back(stripCmdLine);
2027
2028       (*targets)[install_strip] =
2029         this->CreateGlobalTarget(
2030           install_strip, "Installing the project stripped...",
2031           &cpackCommandLines, depends, 0);
2032       }
2033     }
2034 }
2035
2036 //----------------------------------------------------------------------------
2037 const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
2038 {
2039   const char* prop =
2040     this->GetCMakeInstance()->GetProperty("PREDEFINED_TARGETS_FOLDER");
2041
2042   if (prop)
2043     {
2044     return prop;
2045     }
2046
2047   return "CMakePredefinedTargets";
2048 }
2049
2050 //----------------------------------------------------------------------------
2051 bool cmGlobalGenerator::UseFolderProperty()
2052 {
2053   const char* prop = this->GetCMakeInstance()->GetProperty("USE_FOLDERS");
2054
2055   // If this property is defined, let the setter turn this on or off...
2056   //
2057   if (prop)
2058     {
2059     return cmSystemTools::IsOn(prop);
2060     }
2061
2062   // By default, this feature is OFF, since it is not supported in the
2063   // Visual Studio Express editions:
2064   //
2065   return false;
2066 }
2067
2068 //----------------------------------------------------------------------------
2069 cmTarget cmGlobalGenerator::CreateGlobalTarget(
2070   const char* name, const char* message,
2071   const cmCustomCommandLines* commandLines,
2072   std::vector<std::string> depends,
2073   const char* workingDirectory)
2074 {
2075   // Package
2076   cmTarget target;
2077   target.GetProperties().SetCMakeInstance(this->CMakeInstance);
2078   target.SetType(cmTarget::GLOBAL_TARGET, name);
2079   target.SetProperty("EXCLUDE_FROM_ALL","TRUE");
2080
2081   std::vector<std::string> no_outputs;
2082   std::vector<std::string> no_depends;
2083   // Store the custom command in the target.
2084   cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0,
2085                      workingDirectory);
2086   target.GetPostBuildCommands().push_back(cc);
2087   target.SetProperty("EchoString", message);
2088   std::vector<std::string>::iterator dit;
2089   for ( dit = depends.begin(); dit != depends.end(); ++ dit )
2090     {
2091     target.AddUtility(dit->c_str());
2092     }
2093
2094   // Organize in the "predefined targets" folder:
2095   //
2096   if (this->UseFolderProperty())
2097     {
2098     target.SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
2099     }
2100
2101   return target;
2102 }
2103
2104 //----------------------------------------------------------------------------
2105 std::string
2106 cmGlobalGenerator::GenerateRuleFile(std::string const& output) const
2107 {
2108   std::string ruleFile = output;
2109   ruleFile += ".rule";
2110   const char* dir = this->GetCMakeCFGIntDir();
2111   if(dir && dir[0] == '$')
2112     {
2113     cmSystemTools::ReplaceString(ruleFile, dir,
2114                                  cmake::GetCMakeFilesDirectory());
2115     }
2116   return ruleFile;
2117 }
2118
2119 //----------------------------------------------------------------------------
2120 std::string cmGlobalGenerator::GetSharedLibFlagsForLanguage(
2121                                                         std::string const& l)
2122 {
2123   if(this->LanguageToOriginalSharedLibFlags.count(l) > 0)
2124     {
2125     return this->LanguageToOriginalSharedLibFlags[l];
2126     }
2127   return "";
2128 }
2129
2130 //----------------------------------------------------------------------------
2131 void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
2132                                                  const char*, std::string&)
2133 {
2134   // Subclasses that support multiple configurations should implement
2135   // this method to append the subdirectory for the given build
2136   // configuration.
2137 }
2138
2139 //----------------------------------------------------------------------------
2140 cmGlobalGenerator::TargetDependSet const&
2141 cmGlobalGenerator::GetTargetDirectDepends(cmTarget & target)
2142 {
2143   return this->TargetDependencies[&target];
2144 }
2145
2146 void cmGlobalGenerator::AddTarget(cmTarget* t)
2147 {
2148   if(t->IsImported())
2149     {
2150     this->ImportedTargets[t->GetName()] = t;
2151     }
2152   else
2153     {
2154     this->TotalTargets[t->GetName()] = t;
2155     }
2156 }
2157
2158 void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
2159                             cmExternalMakefileProjectGenerator *extraGenerator)
2160 {
2161   this->ExtraGenerator = extraGenerator;
2162   if (this->ExtraGenerator!=0)
2163     {
2164     this->ExtraGenerator->SetGlobalGenerator(this);
2165     }
2166 }
2167
2168 const char* cmGlobalGenerator::GetExtraGeneratorName() const
2169 {
2170   return this->ExtraGenerator==0 ? 0 : this->ExtraGenerator->GetName();
2171 }
2172
2173 void cmGlobalGenerator::FileReplacedDuringGenerate(const std::string& filename)
2174 {
2175   this->FilesReplacedDuringGenerate.push_back(filename);
2176 }
2177
2178 void
2179 cmGlobalGenerator
2180 ::GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames)
2181 {
2182   filenames.clear();
2183   std::copy(
2184     this->FilesReplacedDuringGenerate.begin(),
2185     this->FilesReplacedDuringGenerate.end(),
2186     std::back_inserter(filenames));
2187 }
2188
2189 //----------------------------------------------------------------------------
2190 void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
2191                                       TargetDependSet& originalTargets,
2192                                       cmLocalGenerator* root,
2193                                       GeneratorVector const& generators)
2194 {
2195   // loop over all local generators
2196   for(std::vector<cmLocalGenerator*>::const_iterator i = generators.begin();
2197       i != generators.end(); ++i)
2198     {
2199     // check to make sure generator is not excluded
2200     if(this->IsExcluded(root, *i))
2201       {
2202       continue;
2203       }
2204     cmMakefile* mf = (*i)->GetMakefile();
2205     // Get the targets in the makefile
2206     cmTargets &tgts = mf->GetTargets();
2207     // loop over all the targets
2208     for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
2209       {
2210       cmTarget* target = &l->second;
2211       if(this->IsRootOnlyTarget(target) &&
2212          target->GetMakefile() != root->GetMakefile())
2213         {
2214         continue;
2215         }
2216       // put the target in the set of original targets
2217       originalTargets.insert(target);
2218       // Get the set of targets that depend on target
2219       this->AddTargetDepends(target, projectTargets);
2220       }
2221     }
2222 }
2223
2224 //----------------------------------------------------------------------------
2225 bool cmGlobalGenerator::IsRootOnlyTarget(cmTarget* target)
2226 {
2227   return (target->GetType() == cmTarget::GLOBAL_TARGET ||
2228           strcmp(target->GetName(), this->GetAllTargetName()) == 0);
2229 }
2230
2231 //----------------------------------------------------------------------------
2232 void cmGlobalGenerator::AddTargetDepends(cmTarget* target,
2233                                          TargetDependSet& projectTargets)
2234 {
2235   // add the target itself
2236   if(projectTargets.insert(target).second)
2237     {
2238     // This is the first time we have encountered the target.
2239     // Recursively follow its dependencies.
2240     TargetDependSet const& ts = this->GetTargetDirectDepends(*target);
2241     for(TargetDependSet::const_iterator i = ts.begin(); i != ts.end(); ++i)
2242       {
2243       cmTarget* dtarget = *i;
2244       this->AddTargetDepends(dtarget, projectTargets);
2245       }
2246     }
2247 }
2248
2249
2250 //----------------------------------------------------------------------------
2251 void cmGlobalGenerator::AddToManifest(const char* config,
2252                                       std::string const& f)
2253 {
2254   // Add to the main manifest for this configuration.
2255   this->TargetManifest[config].insert(f);
2256
2257   // Add to the content listing for the file's directory.
2258   std::string dir = cmSystemTools::GetFilenamePath(f);
2259   std::string file = cmSystemTools::GetFilenameName(f);
2260   this->DirectoryContentMap[dir].insert(file);
2261 }
2262
2263 //----------------------------------------------------------------------------
2264 std::set<cmStdString> const&
2265 cmGlobalGenerator::GetDirectoryContent(std::string const& dir, bool needDisk)
2266 {
2267   DirectoryContent& dc = this->DirectoryContentMap[dir];
2268   if(needDisk && !dc.LoadedFromDisk)
2269     {
2270     // Load the directory content from disk.
2271     cmsys::Directory d;
2272     if(d.Load(dir.c_str()))
2273       {
2274       unsigned long n = d.GetNumberOfFiles();
2275       for(unsigned long i = 0; i < n; ++i)
2276         {
2277         const char* f = d.GetFile(i);
2278         if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0)
2279           {
2280           dc.insert(f);
2281           }
2282         }
2283       }
2284     dc.LoadedFromDisk = true;
2285     }
2286   return dc;
2287 }
2288
2289 //----------------------------------------------------------------------------
2290 void
2291 cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
2292                                std::string const& content)
2293 {
2294 #if defined(CMAKE_BUILD_WITH_CMAKE)
2295   // Ignore if there are no outputs.
2296   if(outputs.empty())
2297     {
2298     return;
2299     }
2300
2301   // Compute a hash of the rule.
2302   RuleHash hash;
2303   {
2304   unsigned char const* data =
2305     reinterpret_cast<unsigned char const*>(content.c_str());
2306   int length = static_cast<int>(content.length());
2307   cmsysMD5* sum = cmsysMD5_New();
2308   cmsysMD5_Initialize(sum);
2309   cmsysMD5_Append(sum, data, length);
2310   cmsysMD5_FinalizeHex(sum, hash.Data);
2311   cmsysMD5_Delete(sum);
2312   }
2313
2314   // Shorten the output name (in expected use case).
2315   cmLocalGenerator* lg = this->GetLocalGenerators()[0];
2316   std::string fname = lg->Convert(outputs[0].c_str(),
2317                                   cmLocalGenerator::HOME_OUTPUT);
2318
2319   // Associate the hash with this output.
2320   this->RuleHashes[fname] = hash;
2321 #else
2322   (void)outputs;
2323   (void)content;
2324 #endif
2325 }
2326
2327 //----------------------------------------------------------------------------
2328 void cmGlobalGenerator::CheckRuleHashes()
2329 {
2330 #if defined(CMAKE_BUILD_WITH_CMAKE)
2331   std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory();
2332   std::string pfile = home;
2333   pfile += this->GetCMakeInstance()->GetCMakeFilesDirectory();
2334   pfile += "/CMakeRuleHashes.txt";
2335   this->CheckRuleHashes(pfile, home);
2336   this->WriteRuleHashes(pfile);
2337 #endif
2338 }
2339
2340 //----------------------------------------------------------------------------
2341 void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile,
2342                                         std::string const& home)
2343 {
2344 #if defined(_WIN32) || defined(__CYGWIN__)
2345   std::ifstream fin(pfile.c_str(), std::ios::in | std::ios::binary);
2346 #else
2347   std::ifstream fin(pfile.c_str(), std::ios::in);
2348 #endif
2349   if(!fin)
2350     {
2351     return;
2352     }
2353   std::string line;
2354   std::string fname;
2355   while(cmSystemTools::GetLineFromStream(fin, line))
2356     {
2357     // Line format is a 32-byte hex string followed by a space
2358     // followed by a file name (with no escaping).
2359
2360     // Skip blank and comment lines.
2361     if(line.size() < 34 || line[0] == '#')
2362       {
2363       continue;
2364       }
2365
2366     // Get the filename.
2367     fname = line.substr(33, line.npos);
2368
2369     // Look for a hash for this file's rule.
2370     std::map<cmStdString, RuleHash>::const_iterator rhi =
2371       this->RuleHashes.find(fname);
2372     if(rhi != this->RuleHashes.end())
2373       {
2374       // Compare the rule hash in the file to that we were given.
2375       if(strncmp(line.c_str(), rhi->second.Data, 32) != 0)
2376         {
2377         // The rule has changed.  Delete the output so it will be
2378         // built again.
2379         fname = cmSystemTools::CollapseFullPath(fname.c_str(), home.c_str());
2380         cmSystemTools::RemoveFile(fname.c_str());
2381         }
2382       }
2383     else
2384       {
2385       // We have no hash for a rule previously listed.  This may be a
2386       // case where a user has turned off a build option and might
2387       // want to turn it back on later, so do not delete the file.
2388       // Instead, we keep the rule hash as long as the file exists so
2389       // that if the feature is turned back on and the rule has
2390       // changed the file is still rebuilt.
2391       std::string fpath =
2392         cmSystemTools::CollapseFullPath(fname.c_str(), home.c_str());
2393       if(cmSystemTools::FileExists(fpath.c_str()))
2394         {
2395         RuleHash hash;
2396         strncpy(hash.Data, line.c_str(), 32);
2397         this->RuleHashes[fname] = hash;
2398         }
2399       }
2400     }
2401 }
2402
2403 //----------------------------------------------------------------------------
2404 void cmGlobalGenerator::WriteRuleHashes(std::string const& pfile)
2405 {
2406   // Now generate a new persistence file with the current hashes.
2407   if(this->RuleHashes.empty())
2408     {
2409     cmSystemTools::RemoveFile(pfile.c_str());
2410     }
2411   else
2412     {
2413     cmGeneratedFileStream fout(pfile.c_str());
2414     fout << "# Hashes of file build rules.\n";
2415     for(std::map<cmStdString, RuleHash>::const_iterator
2416           rhi = this->RuleHashes.begin(); rhi != this->RuleHashes.end(); ++rhi)
2417       {
2418       fout.write(rhi->second.Data, 32);
2419       fout << " " << rhi->first << "\n";
2420       }
2421     }
2422 }
2423
2424 //----------------------------------------------------------------------------
2425 void cmGlobalGenerator::WriteSummary()
2426 {
2427   cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
2428
2429   // Record all target directories in a central location.
2430   std::string fname = mf->GetHomeOutputDirectory();
2431   fname += cmake::GetCMakeFilesDirectory();
2432   fname += "/TargetDirectories.txt";
2433   cmGeneratedFileStream fout(fname.c_str());
2434
2435   // Generate summary information files for each target.
2436   std::string dir;
2437   for(std::map<cmStdString,cmTarget *>::const_iterator ti =
2438         this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
2439     {
2440     this->WriteSummary(ti->second);
2441     fout << ti->second->GetSupportDirectory() << "\n";
2442     }
2443 }
2444
2445 //----------------------------------------------------------------------------
2446 void cmGlobalGenerator::WriteSummary(cmTarget* target)
2447 {
2448   // Place the labels file in a per-target support directory.
2449   std::string dir = target->GetSupportDirectory();
2450   std::string file = dir;
2451   file += "/Labels.txt";
2452
2453   // Check whether labels are enabled for this target.
2454   if(const char* value = target->GetProperty("LABELS"))
2455     {
2456     cmSystemTools::MakeDirectory(dir.c_str());
2457     cmGeneratedFileStream fout(file.c_str());
2458
2459     // List the target-wide labels.  All sources in the target get
2460     // these labels.
2461     std::vector<std::string> labels;
2462     cmSystemTools::ExpandListArgument(value, labels);
2463     if(!labels.empty())
2464       {
2465       fout << "# Target labels\n";
2466       for(std::vector<std::string>::const_iterator li = labels.begin();
2467           li != labels.end(); ++li)
2468         {
2469         fout << " " << *li << "\n";
2470         }
2471       }
2472
2473     // List the source files with any per-source labels.
2474     fout << "# Source files and their labels\n";
2475     std::vector<cmSourceFile*> const& sources = target->GetSourceFiles();
2476     for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
2477         si != sources.end(); ++si)
2478       {
2479       cmSourceFile* sf = *si;
2480       fout << sf->GetFullPath() << "\n";
2481       if(const char* svalue = sf->GetProperty("LABELS"))
2482         {
2483         labels.clear();
2484         cmSystemTools::ExpandListArgument(svalue, labels);
2485         for(std::vector<std::string>::const_iterator li = labels.begin();
2486             li != labels.end(); ++li)
2487           {
2488           fout << " " << *li << "\n";
2489           }
2490         }
2491       }
2492     }
2493   else
2494     {
2495     cmSystemTools::RemoveFile(file.c_str());
2496     }
2497 }
2498
2499 //----------------------------------------------------------------------------
2500 // static
2501 std::string cmGlobalGenerator::EscapeJSON(const std::string& s) {
2502   std::string result;
2503   for (std::string::size_type i = 0; i < s.size(); ++i) {
2504     if (s[i] == '"' || s[i] == '\\') {
2505       result += '\\';
2506     }
2507     result += s[i];
2508   }
2509   return result;
2510 }