cmGlobalGenerator.cxx 90.5 KB
Newer Older
1
2
3
/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Ken Martin's avatar
Ken Martin committed
4

5
6
  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.
Ken Martin's avatar
Ken Martin committed
7

8
9
10
11
  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
Alexander Neundorf's avatar
   
Alexander Neundorf committed
12
13
14
15
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "windows.h" // this must be first to define GetCurrentDirectory
#endif

Ken Martin's avatar
Ken Martin committed
16
17
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
Alexander Neundorf's avatar
   
Alexander Neundorf committed
18
#include "cmExternalMakefileProjectGenerator.h"
Ken Martin's avatar
Ken Martin committed
19
20
#include "cmake.h"
#include "cmMakefile.h"
21
#include "cmQtAutoGenerators.h"
22
#include "cmSourceFile.h"
23
#include "cmVersion.h"
24
#include "cmTargetExport.h"
25
#include "cmComputeTargetDepends.h"
26
#include "cmGeneratedFileStream.h"
27
#include "cmGeneratorTarget.h"
28
#include "cmGeneratorExpression.h"
29
#include "cmGeneratorExpressionEvaluationFile.h"
30
#include "cmExportBuildFileGenerator.h"
31

32
33
#include <cmsys/Directory.hxx>

34
35
36
37
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include <cmsys/MD5.h>
#endif

38
#include <stdlib.h> // required for atof
Ken Martin's avatar
Ken Martin committed
39

40
41
#include <assert.h>

Ken Martin's avatar
updates    
Ken Martin committed
42
43
cmGlobalGenerator::cmGlobalGenerator()
{
44
45
46
  // By default the .SYMBOLIC dependency is not needed on symbolic rules.
  this->NeedSymbolicMark = false;

47
  // by default use the native paths
Ken Martin's avatar
Ken Martin committed
48
  this->ForceUnixPaths = false;
49
50

  // By default do not try to support color.
51
  this->ToolSupportsColor = false;
52
53
54

  // By default do not use link scripts.
  this->UseLinkScript = false;
55

56
57
  // Whether an install target is needed.
  this->InstallTargetEnabled = false;
58
59
60

  // how long to let try compiles run
  this->TryCompileTimeout = 0;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
61
62

  this->ExtraGenerator = 0;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
63
  this->CurrentLocalGenerator = 0;
64
  this->TryCompileOuterMakefile = 0;
Ken Martin's avatar
updates    
Ken Martin committed
65
66
}

Ken Martin's avatar
Ken Martin committed
67
cmGlobalGenerator::~cmGlobalGenerator()
Alexander Neundorf's avatar
   
Alexander Neundorf committed
68
{
69
  this->ClearGeneratorMembers();
Alexander Neundorf's avatar
   
Alexander Neundorf committed
70
71
72
73
74

  if (this->ExtraGenerator)
    {
    delete this->ExtraGenerator;
    }
Ken Martin's avatar
Ken Martin committed
75
76
}

77
78
79
80
81
82
83
84
85
86
87
88
89
90
bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts)
{
  cmOStringStream e;
  e <<
    "Generator\n"
    "  " << this->GetName() << "\n"
    "does not support toolset specification, but toolset\n"
    "  " << ts << "\n"
    "was specified.";
  this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
                                    cmListFileBacktrace());
  return false;
}

91
92
void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
                                                cmMakefile *mf,
93
94
                                                bool optional)
{
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  std::string langComp = "CMAKE_";
  langComp += lang;
  langComp += "_COMPILER";

  if(!mf->GetDefinition(langComp.c_str()))
    {
    if(!optional)
      {
      cmSystemTools::Error(langComp.c_str(),
                           " not set, after EnableLanguage");
      }
    return;
    }
  const char* name = mf->GetRequiredDefinition(langComp.c_str());
  std::string path;
  if(!cmSystemTools::FileIsFullPath(name))
    {
    path = cmSystemTools::FindProgram(name);
    }
  else
    {
    path = name;
    }
  if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str()))
      && (optional==false))
    {
121
    return;
122
123
124
125
126
127
    }
  std::string doc = lang;
  doc += " compiler.";
  const char* cname = this->GetCMakeInstance()->
    GetCacheManager()->GetCacheValue(langComp.c_str());
  std::string changeVars;
128
  if(cname && !optional)
129
    {
130
131
132
133
134
135
136
137
138
    std::string cnameString;
    if(!cmSystemTools::FileIsFullPath(cname))
      {
      cnameString = cmSystemTools::FindProgram(cname);
      }
    else
      {
      cnameString = cname;
      }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    std::string pathString = path;
    // get rid of potentially multiple slashes:
    cmSystemTools::ConvertToUnixSlashes(cnameString);
    cmSystemTools::ConvertToUnixSlashes(pathString);
    if (cnameString != pathString)
      {
      const char* cvars =
        this->GetCMakeInstance()->GetProperty(
          "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
      if(cvars)
        {
        changeVars += cvars;
        changeVars += ";";
        }
      changeVars += langComp;
      changeVars += ";";
      changeVars += cname;
      this->GetCMakeInstance()->SetProperty(
        "__CMAKE_DELETE_CACHE_CHANGE_VARS_",
        changeVars.c_str());
      }
    }
  mf->AddCacheDefinition(langComp.c_str(), path.c_str(),
                         doc.c_str(), cmCacheManager::FILEPATH);
}

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
{
  this->BuildExportSets[gen->GetMainExportFileName()] = gen;
}

bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
{
  std::map<std::string, cmExportBuildFileGenerator*>::iterator it
                                          = this->BuildExportSets.find(file);
  if (it != this->BuildExportSets.end())
    {
    bool result = it->second->GenerateImportFile();
    delete it->second;
    it->second = 0;
    this->BuildExportSets.erase(it);
    return result;
    }
  return false;
}

bool
cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
{
  const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
                                      = this->BuildExportSets.find(filename);
  return it != this->BuildExportSets.end();
}

193
194
// Find the make program for the generator, required for try compiles
void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
195
{
Ken Martin's avatar
Ken Martin committed
196
  if(this->FindMakeProgramFile.size() == 0)
197
198
199
    {
    cmSystemTools::Error(
      "Generator implementation error, "
Ken Martin's avatar
Ken Martin committed
200
      "all generators must specify this->FindMakeProgramFile");
201
202
203
204
    }
  if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
     || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
    {
Alexander Neundorf's avatar
   
Alexander Neundorf committed
205
    std::string setMakeProgram =
Ken Martin's avatar
Ken Martin committed
206
      mf->GetModulesFile(this->FindMakeProgramFile.c_str());
207
208
209
210
    if(setMakeProgram.size())
      {
      mf->ReadListFile(0, setMakeProgram.c_str());
      }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
211
    }
212
213
214
  if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
     || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
    {
215
216
217
218
219
    cmOStringStream err;
    err << "CMake was unable to find a build program corresponding to \""
        << this->GetName() << "\".  CMAKE_MAKE_PROGRAM is not set.  You "
        << "probably need to select a different build tool.";
    cmSystemTools::Error(err.str().c_str());
220
    cmSystemTools::SetFatalErrorOccured();
221
222
    return;
    }
223
  std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
224
225
226
  // if there are spaces in the make program use short path
  // but do not short path the actual program name, as
  // this can cause trouble with VSExpress
227
228
  if(makeProgram.find(' ') != makeProgram.npos)
    {
229
230
231
232
233
    std::string dir;
    std::string file;
    cmSystemTools::SplitProgramPath(makeProgram.c_str(),
                                    dir, file);
    std::string saveFile = file;
234
    cmSystemTools::GetShortPath(makeProgram.c_str(), makeProgram);
235
236
237
238
239
    cmSystemTools::SplitProgramPath(makeProgram.c_str(),
                                    dir, file);
    makeProgram = dir;
    makeProgram += "/";
    makeProgram += saveFile;
240
241
242
    mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
                           "make program",
                           cmCacheManager::FILEPATH);
243
    }
244

245
246
247
248
249
250
251
252
  if(makeProgram.find("xcodebuild") != makeProgram.npos)
    {
    // due to the text file busy /bin/sh problem with xcodebuild
    // use the cmakexbuild wrapper instead.  This program
    // will run xcodebuild and if it sees the error text file busy
    // it will stop forwarding output, and let the build finish.
    // Then it will retry the build.  It will continue this
    // untill no text file busy errors occur.
Alexander Neundorf's avatar
   
Alexander Neundorf committed
253
    std::string cmakexbuild =
254
255
256
      this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
    cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
    cmakexbuild += "cmakexbuild";
Alexander Neundorf's avatar
   
Alexander Neundorf committed
257
258

    mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM",
259
260
261
                           cmakexbuild.c_str(),
                           "make program",
                           cmCacheManager::FILEPATH);
262
    }
263
264
265
}

// enable the given language
266
267
//
// The following files are loaded in this order:
Alexander Neundorf's avatar
   
Alexander Neundorf committed
268
//
269
// First figure out what OS we are running on:
Alexander Neundorf's avatar
   
Alexander Neundorf committed
270
//
Ken Martin's avatar
Ken Martin committed
271
// CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake
Alexander Neundorf's avatar
   
Alexander Neundorf committed
272
//   CMakeDetermineSystem.cmake - figure out os info and create
Alexander Neundorf's avatar
   
Alexander Neundorf committed
273
//                                CMakeSystem.cmake IF CMAKE_SYSTEM
Ken Martin's avatar
Ken Martin committed
274
//                                not set
Alexander Neundorf's avatar
   
Alexander Neundorf committed
275
//   CMakeSystem.cmake - configured file created by
Alexander Neundorf's avatar
   
Alexander Neundorf committed
276
//                       CMakeDetermineSystem.cmake IF CMAKE_SYSTEM_LOADED
277
278

// Next try and enable all languages found in the languages vector
Alexander Neundorf's avatar
   
Alexander Neundorf committed
279
//
280
// FOREACH LANG in languages
Alexander Neundorf's avatar
   
Alexander Neundorf committed
281
//   CMake(LANG)Compiler.cmake - configured file create by
Ken Martin's avatar
Ken Martin committed
282
//                               CMakeDetermine(LANG)Compiler.cmake
Alexander Neundorf's avatar
   
Alexander Neundorf committed
283
//     CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
Ken Martin's avatar
Ken Martin committed
284
//                                          creates CMake(LANG)Compiler.cmake
Alexander Neundorf's avatar
   
Alexander Neundorf committed
285
286
//     CMake(LANG)Compiler.cmake - configured file created by
//                                 CMakeDetermine(LANG)Compiler.cmake
287
//
Alexander Neundorf's avatar
   
Alexander Neundorf committed
288
// CMakeSystemSpecificInformation.cmake
Ken Martin's avatar
Ken Martin committed
289
290
//   - includes Platform/${CMAKE_SYSTEM_NAME}.cmake
//     may use compiler stuff
291
292

// FOREACH LANG in languages
Alexander Neundorf's avatar
   
Alexander Neundorf committed
293
//   CMake(LANG)Information.cmake
Ken Martin's avatar
Ken Martin committed
294
295
//     - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake
//   CMakeTest(LANG)Compiler.cmake
Alexander Neundorf's avatar
   
Alexander Neundorf committed
296
//     - Make sure the compiler works with a try compile if
Ken Martin's avatar
Ken Martin committed
297
//       CMakeDetermine(LANG) was loaded
Alexander Neundorf's avatar
   
Alexander Neundorf committed
298
//
299
// Now load a few files that can override values set in any of the above
Alexander Neundorf's avatar
   
Alexander Neundorf committed
300
// (PROJECTNAME)Compatibility.cmake
Ken Martin's avatar
Ken Martin committed
301
302
//   - load any backwards compatibility stuff for current project
// ${CMAKE_USER_MAKE_RULES_OVERRIDE}
Alexander Neundorf's avatar
   
Alexander Neundorf committed
303
//   - allow users a chance to override system variables
304
305
306
//
//

Alexander Neundorf's avatar
   
Alexander Neundorf committed
307
void
308
cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
309
                                  cmMakefile *mf, bool optional)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
310
{
311
  if(languages.size() == 0)
312
313
314
315
316
    {
    cmSystemTools::Error("EnableLanguage must have a lang specified!");
    cmSystemTools::SetFatalErrorOccured();
    return;
    }
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

  if(this->TryCompileOuterMakefile)
    {
    // In a try-compile we can only enable languages provided by caller.
    for(std::vector<std::string>::const_iterator li = languages.begin();
        li != languages.end(); ++li)
      {
      if(*li == "NONE")
        {
        this->SetLanguageEnabled("NONE", mf);
        }
      else
        {
        const char* lang = li->c_str();
        if(this->LanguagesReady.find(lang) == this->LanguagesReady.end())
          {
          cmOStringStream e;
          e << "The test project needs language "
            << lang << " which is not enabled.";
          this->TryCompileOuterMakefile
            ->IssueMessage(cmake::FATAL_ERROR, e.str());
          cmSystemTools::SetFatalErrorOccured();
          return;
          }
        }
      }
    }

345
346
  bool fatalError = false;

347
  mf->AddDefinition("RUN_CONFIGURE", true);
348
  std::string rootBin = mf->GetHomeOutputDirectory();
349
  rootBin += cmake::GetCMakeFilesDirectory();
Alexander Neundorf's avatar
   
Alexander Neundorf committed
350

351
352
  // If the configuration files path has been set,
  // then we are in a try compile and need to copy the enable language
353
  // files from the parent cmake bin dir, into the try compile bin dir
Ken Martin's avatar
Ken Martin committed
354
  if(this->ConfiguredFilesPath.size())
355
    {
Ken Martin's avatar
Ken Martin committed
356
    rootBin = this->ConfiguredFilesPath;
357
    }
358
359
  rootBin += "/";
  rootBin += cmVersion::GetCMakeVersion();
360

361
  // set the dir for parent files so they can be used by modules
362
  mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR",rootBin.c_str());
Alexander Neundorf's avatar
   
Alexander Neundorf committed
363

364
  // find and make sure CMAKE_MAKE_PROGRAM is defined
365
366
  this->FindMakeProgram(mf);

367
368
369
370
371
372
373
374
375
376
  // try and load the CMakeSystem.cmake if it is there
  std::string fpath = rootBin;
  if(!mf->GetDefinition("CMAKE_SYSTEM_LOADED"))
    {
    fpath += "/CMakeSystem.cmake";
    if(cmSystemTools::FileExists(fpath.c_str()))
      {
      mf->ReadListFile(0,fpath.c_str());
      }
    }
377
  //  Load the CMakeDetermineSystem.cmake file and find out
378
  // what platform we are running on
Alexander Neundorf's avatar
   
Alexander Neundorf committed
379
  if (!mf->GetDefinition("CMAKE_SYSTEM"))
Andy Cedilnik's avatar
Andy Cedilnik committed
380
    {
Alexander Neundorf's avatar
   
Alexander Neundorf committed
381
#if defined(_WIN32) && !defined(__CYGWIN__)
382
383
384
385
386
387
388
389
    /* Windows version number data.  */
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(osvi));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx (&osvi);
    cmOStringStream windowsVersionString;
    windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
    windowsVersionString.str();
390
    mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
Ken Martin's avatar
Ken Martin committed
391
                      windowsVersionString.str().c_str());
392
#endif
Andy Cedilnik's avatar
Andy Cedilnik committed
393
    // Read the DetermineSystem file
394
    std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
Andy Cedilnik's avatar
Andy Cedilnik committed
395
    mf->ReadListFile(0, systemFile.c_str());
396
397
398
    // load the CMakeSystem.cmake from the binary directory
    // this file is configured by the CMakeDetermineSystem.cmake file
    fpath = rootBin;
399
400
401
    fpath += "/CMakeSystem.cmake";
    mf->ReadListFile(0,fpath.c_str());
    }
402
  std::map<cmStdString, bool> needTestLanguage;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
403
  std::map<cmStdString, bool> needSetLanguageEnabledMaps;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
404
  // foreach language
405
  // load the CMakeDetermine(LANG)Compiler.cmake file to find
Alexander Neundorf's avatar
   
Alexander Neundorf committed
406
  // the compiler
407

408
409
410
411
  for(std::vector<std::string>::const_iterator l = languages.begin();
      l != languages.end(); ++l)
    {
    const char* lang = l->c_str();
Alexander Neundorf's avatar
   
Alexander Neundorf committed
412
    needSetLanguageEnabledMaps[lang] = false;
Bill Hoffman's avatar
Bill Hoffman committed
413
414
415
416
417
    if(*l == "NONE")
      {
      this->SetLanguageEnabled("NONE", mf);
      continue;
      }
418
419
420
    std::string loadedLang = "CMAKE_";
    loadedLang +=  lang;
    loadedLang += "_COMPILER_LOADED";
421
    if(!mf->GetDefinition(loadedLang.c_str()))
422
423
424
425
426
      {
      fpath = rootBin;
      fpath += "/CMake";
      fpath += lang;
      fpath += "Compiler.cmake";
427
428
429
430

      // If the existing build tree was already configured with this
      // version of CMake then try to load the configured file first
      // to avoid duplicate compiler tests.
431
      if(cmSystemTools::FileExists(fpath.c_str()))
432
433
434
        {
        if(!mf->ReadListFile(0,fpath.c_str()))
          {
435
          cmSystemTools::Error("Could not find cmake module file: ",
Ken Martin's avatar
Ken Martin committed
436
                               fpath.c_str());
437
          }
Ken Martin's avatar
Ken Martin committed
438
439
        // if this file was found then the language was already determined
        // to be working
440
        needTestLanguage[lang] = false;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
441
442
        this->SetLanguageEnabledFlag(lang, mf);
        needSetLanguageEnabledMaps[lang] = true;
Ken Martin's avatar
Ken Martin committed
443
        // this can only be called after loading CMake(LANG)Compiler.cmake
444
445
        }
      }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
446

447
    if(!this->GetLanguageEnabled(lang) )
Alexander Neundorf's avatar
   
Alexander Neundorf committed
448
      {
Ken Martin's avatar
Ken Martin committed
449
      if (this->CMakeInstance->GetIsInTryCompile())
450
        {
451
        cmSystemTools::Error("This should not have happened. "
Ken Martin's avatar
Ken Martin committed
452
453
454
                             "If you see this message, you are probably "
                             "using a broken CMakeLists.txt file or a "
                             "problematic release of CMake");
455
        }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
456
      // if the CMake(LANG)Compiler.cmake file was not found then
457
      // load CMakeDetermine(LANG)Compiler.cmake
458
459
460
      std::string determineCompiler = "CMakeDetermine";
      determineCompiler += lang;
      determineCompiler += "Compiler.cmake";
Alexander Neundorf's avatar
   
Alexander Neundorf committed
461
      std::string determineFile =
462
        mf->GetModulesFile(determineCompiler.c_str());
463
464
      if(!mf->ReadListFile(0,determineFile.c_str()))
        {
465
        cmSystemTools::Error("Could not find cmake module file: ",
466
                             determineFile.c_str());
Alexander Neundorf's avatar
   
Alexander Neundorf committed
467
        }
468
      needTestLanguage[lang] = true;
469
470
471
472
      // Some generators like visual studio should not use the env variables
      // So the global generator can specify that in this variable
      if(!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV"))
        {
Ken Martin's avatar
Ken Martin committed
473
474
475
        // put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
        // into the environment, in case user scripts want to run
        // configure, or sub cmakes
476
477
478
479
480
481
482
        std::string compilerName = "CMAKE_";
        compilerName += lang;
        compilerName += "_COMPILER";
        std::string compilerEnv = "CMAKE_";
        compilerEnv += lang;
        compilerEnv += "_COMPILER_ENV_VAR";
        std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str());
Alexander Neundorf's avatar
   
Alexander Neundorf committed
483
        std::string envVarValue =
Ken Martin's avatar
Ken Martin committed
484
          mf->GetRequiredDefinition(compilerName.c_str());
485
486
487
488
489
        std::string env = envVar;
        env += "=";
        env += envVarValue;
        cmSystemTools::PutEnv(env.c_str());
        }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
490
491
492

      // if determineLanguage was called then load the file it
      // configures CMake(LANG)Compiler.cmake
493
494
495
496
497
498
      fpath = rootBin;
      fpath += "/CMake";
      fpath += lang;
      fpath += "Compiler.cmake";
      if(!mf->ReadListFile(0,fpath.c_str()))
        {
499
        cmSystemTools::Error("Could not find cmake module file: ",
Ken Martin's avatar
Ken Martin committed
500
                             fpath.c_str());
501
        }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
502
503
      this->SetLanguageEnabledFlag(lang, mf);
      needSetLanguageEnabledMaps[lang] = true;
Ken Martin's avatar
Ken Martin committed
504
505
506
507
      // this can only be called after loading CMake(LANG)Compiler.cmake
      // the language must be enabled for try compile to work, but we do
      // not know if it is a working compiler yet so set the test language
      // flag
508
      needTestLanguage[lang] = true;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
509
      } // end if(!this->GetLanguageEnabled(lang) )
510
    }  // end loop over languages
Alexander Neundorf's avatar
   
Alexander Neundorf committed
511

512
  // **** Load the system specific information if not yet loaded
513
  if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
Bill Hoffman's avatar
Bill Hoffman committed
514
    {
515
516
517
    fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
    if(!mf->ReadListFile(0,fpath.c_str()))
      {
518
      cmSystemTools::Error("Could not find cmake module file: ",
Ken Martin's avatar
Ken Martin committed
519
                           fpath.c_str());
520
      }
Bill Hoffman's avatar
Bill Hoffman committed
521
    }
522
523
  // loop over languages again loading CMake(LANG)Information.cmake
  //
524
525
526
527
  for(std::vector<std::string>::const_iterator l = languages.begin();
      l != languages.end(); ++l)
    {
    const char* lang = l->c_str();
Bill Hoffman's avatar
Bill Hoffman committed
528
529
530
531
532
    if(*l == "NONE")
      {
      this->SetLanguageEnabled("NONE", mf);
      continue;
      }
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591

    // Check that the compiler was found.
    std::string compilerName = "CMAKE_";
    compilerName += lang;
    compilerName += "_COMPILER";
    std::string compilerEnv = "CMAKE_";
    compilerEnv += lang;
    compilerEnv += "_COMPILER_ENV_VAR";
    cmOStringStream noCompiler;
    const char* compilerFile = mf->GetDefinition(compilerName.c_str());
    if(!compilerFile || !*compilerFile ||
       cmSystemTools::IsNOTFOUND(compilerFile))
      {
      noCompiler <<
        "No " << compilerName << " could be found.\n"
        ;
      }
    else if(strcmp(lang, "RC") != 0)
      {
      if(!cmSystemTools::FileIsFullPath(compilerFile))
        {
        noCompiler <<
          "The " << compilerName << ":\n"
          "  " << compilerFile << "\n"
          "is not a full path and was not found in the PATH.\n"
          ;
        }
      else if(!cmSystemTools::FileExists(compilerFile))
        {
        noCompiler <<
          "The " << compilerName << ":\n"
          "  " << compilerFile << "\n"
          "is not a full path to an existing compiler tool.\n"
          ;
        }
      }
    if(!noCompiler.str().empty())
      {
      // Skip testing this language since the compiler is not found.
      needTestLanguage[lang] = false;
      if(!optional)
        {
        // The compiler was not found and it is not optional.  Remove
        // CMake(LANG)Compiler.cmake so we try again next time CMake runs.
        std::string compilerLangFile = rootBin;
        compilerLangFile += "/CMake";
        compilerLangFile += lang;
        compilerLangFile += "Compiler.cmake";
        cmSystemTools::RemoveFile(compilerLangFile.c_str());
        if(!this->CMakeInstance->GetIsInTryCompile())
          {
          this->PrintCompilerAdvice(noCompiler, lang,
                                    mf->GetDefinition(compilerEnv.c_str()));
          mf->IssueMessage(cmake::FATAL_ERROR, noCompiler.str());
          fatalError = true;
          }
        }
      }

592
593
594
595
    std::string langLoadedVar = "CMAKE_";
    langLoadedVar += lang;
    langLoadedVar += "_INFORMATION_LOADED";
    if (!mf->GetDefinition(langLoadedVar.c_str()))
Alexander Neundorf's avatar
   
Alexander Neundorf committed
596
      {
597
598
599
      fpath = "CMake";
      fpath +=  lang;
      fpath += "Information.cmake";
600
601
      std::string informationFile = mf->GetModulesFile(fpath.c_str());
      if (informationFile.empty())
602
        {
603
        cmSystemTools::Error("Could not find cmake module file: ",
Ken Martin's avatar
Ken Martin committed
604
                             fpath.c_str());
605
        }
606
607
      else if(!mf->ReadListFile(0, informationFile.c_str()))
        {
608
        cmSystemTools::Error("Could not process cmake module file: ",
609
610
                             informationFile.c_str());
        }
611
      }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
612
613
614
615
    if (needSetLanguageEnabledMaps[lang])
      {
      this->SetLanguageEnabledMaps(lang, mf);
      }
616
    this->LanguagesReady.insert(lang);
Alexander Neundorf's avatar
   
Alexander Neundorf committed
617

618
    // Test the compiler for the language just setup
619
    // (but only if a compiler has been actually found)
620
621
    // At this point we should have enough info for a try compile
    // which is used in the backward stuff
622
    // If the language is untested then test it now with a try compile.
623
    if(needTestLanguage[lang])
624
      {
Ken Martin's avatar
Ken Martin committed
625
      if (!this->CMakeInstance->GetIsInTryCompile())
626
        {
627
628
629
630
631
        std::string testLang = "CMakeTest";
        testLang += lang;
        testLang += "Compiler.cmake";
        std::string ifpath = mf->GetModulesFile(testLang.c_str());
        if(!mf->ReadListFile(0,ifpath.c_str()))
632
          {
633
          cmSystemTools::Error("Could not find cmake module file: ",
634
                               ifpath.c_str());
635
          }
636
637
638
        std::string compilerWorks = "CMAKE_";
        compilerWorks += lang;
        compilerWorks += "_COMPILER_WORKS";
Ken Martin's avatar
Ken Martin committed
639
640
641
        // if the compiler did not work, then remove the
        // CMake(LANG)Compiler.cmake file so that it will get tested the
        // next time cmake is run
642
        if(!mf->IsOn(compilerWorks.c_str()))
Alexander Neundorf's avatar
   
Alexander Neundorf committed
643
          {
644
645
646
647
          std::string compilerLangFile = rootBin;
          compilerLangFile += "/CMake";
          compilerLangFile += lang;
          compilerLangFile += "Compiler.cmake";
648
          cmSystemTools::RemoveFile(compilerLangFile.c_str());
649
650
651
          }
        } // end if in try compile
      } // end need test language
652
653
654
655
656
657
658
659
660
661
    // Store the shared library flags so that we can satisfy CMP0018
    std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_";
    sharedLibFlagsVar += lang;
    sharedLibFlagsVar += "_FLAGS";
    const char* sharedLibFlags =
      mf->GetSafeDefinition(sharedLibFlagsVar.c_str());
    if (sharedLibFlags)
      {
      this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags;
      }
662
663
664

    // Translate compiler ids for compatibility.
    this->CheckCompilerIdCompatibility(mf, lang);
665
    } // end for each language
Alexander Neundorf's avatar
   
Alexander Neundorf committed
666

Ken Martin's avatar
Ken Martin committed
667
668
669
  // Now load files that can override any settings on the platform or for
  // the project First load the project compatibility file if it is in
  // cmake
670
671
  std::string projectCompatibility = mf->GetDefinition("CMAKE_ROOT");
  projectCompatibility += "/Modules/";
672
  projectCompatibility += mf->GetSafeDefinition("PROJECT_NAME");
673
674
675
  projectCompatibility += "Compatibility.cmake";
  if(cmSystemTools::FileExists(projectCompatibility.c_str()))
    {
Alexander Neundorf's avatar
   
Alexander Neundorf committed
676
    mf->ReadListFile(0,projectCompatibility.c_str());
677
    }
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

  if(fatalError)
    {
    cmSystemTools::SetFatalErrorOccured();
    }
}

//----------------------------------------------------------------------------
void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os,
                                            std::string lang,
                                            const char* envVar)
{
  // Subclasses override this method if they do not support this advice.
  os <<
    "Tell CMake where to find the compiler by setting "
    ;
  if(envVar)
    {
    os <<
      "either the environment variable \"" << envVar << "\" or "
      ;
    }
  os <<
    "the CMake cache entry CMAKE_" << lang << "_COMPILER "
    "to the full path to the compiler, or to the compiler name "
    "if it is in the PATH."
    ;
705
706
}

707
//----------------------------------------------------------------------------
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf,
                                                     std::string lang)
{
  std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID";
  const char* compilerId = mf->GetDefinition(compilerIdVar.c_str());
  if(compilerId && strcmp(compilerId, "AppleClang") == 0)
    {
    cmPolicies* policies = this->CMakeInstance->GetPolicies();
    switch(mf->GetPolicyStatus(cmPolicies::CMP0025))
      {
      case cmPolicies::WARN:
        if(!this->CMakeInstance->GetIsInTryCompile())
          {
          cmOStringStream w;
          w << policies->GetPolicyWarning(cmPolicies::CMP0025) << "\n"
            "Converting " << lang <<
            " compiler id \"AppleClang\" to \"Clang\" for compatibility."
            ;
          mf->IssueMessage(cmake::AUTHOR_WARNING, w.str());
          }
      case cmPolicies::OLD:
        // OLD behavior is to convert AppleClang to Clang.
        mf->AddDefinition(compilerIdVar.c_str(), "Clang");
        break;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        mf->IssueMessage(
          cmake::FATAL_ERROR,
          policies->GetRequiredPolicyError(cmPolicies::CMP0025)
          );
      case cmPolicies::NEW:
        // NEW behavior is to keep AppleClang.
        break;
      }
    }
}

745
746
747
//----------------------------------------------------------------------------
const char*
cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
748
{
749
  if(const char* lang = source.GetLanguage())
750
    {
751
752
753
754
    if(this->LanguageToOutputExtension.count(lang) > 0)
      {
      return this->LanguageToOutputExtension[lang].c_str();
      }
755
    }
756
  else
757
758
759
760
    {
    // if no language is found then check to see if it is already an
    // ouput extension for some language.  In that case it should be ignored
    // and in this map, so it will not be compiled but will just be used.
761
762
    std::string const& ext = source.GetExtension();
    if(!ext.empty())
763
      {
764
765
766
767
      if(this->OutputExtensions.count(ext))
        {
        return ext.c_str();
        }
768
769
      }
    }
770
  return "";
771
772
773
}


774
775
const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext)
{
Ken Martin's avatar
Ken Martin committed
776
777
  // if there is an extension and it starts with . then move past the
  // . because the extensions are not stored with a .  in the map
778
779
780
781
  if(ext && *ext == '.')
    {
    ++ext;
    }
Ken Martin's avatar
Ken Martin committed
782
  if(this->ExtensionToLanguage.count(ext) > 0)
783
    {
Ken Martin's avatar
Ken Martin committed
784
    return this->ExtensionToLanguage[ext].c_str();
785
786
787
    }
  return 0;
}
788

Alexander Neundorf's avatar
   
Alexander Neundorf committed
789
790
791
792
793
794
/* SetLanguageEnabled() is now split in two parts:
at first the enabled-flag is set. This can then be used in EnabledLanguage()
for checking whether the language is already enabled. After setting this
flag still the values from the cmake variables have to be copied into the
internal maps, this is done in SetLanguageEnabledMaps() which is called
after the system- and compiler specific files have been loaded.
795
796
797
798
799

This split was done originally so that compiler-specific configuration
files could change the object file extension
(CMAKE_<LANG>_OUTPUT_EXTENSION) before the CMake variables were copied
to the C++ maps.
Alexander Neundorf's avatar
   
Alexander Neundorf committed
800
*/
801
void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
Ken Martin's avatar
Ken Martin committed
802
{
Alexander Neundorf's avatar
   
Alexander Neundorf committed
803
804
805
806
  this->SetLanguageEnabledFlag(l, mf);
  this->SetLanguageEnabledMaps(l, mf);
}

807
void cmGlobalGenerator::SetLanguageEnabledFlag(const char* l, cmMakefile* mf)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
808
809
{
  this->LanguageEnabled[l] = true;
810
811
812
813
814
815
816

  // Fill the language-to-extension map with the current variable
  // settings to make sure it is available for the try_compile()
  // command source file signature.  In SetLanguageEnabledMaps this
  // will be done again to account for any compiler- or
  // platform-specific entries.
  this->FillExtensionToLanguageMap(l, mf);
Alexander Neundorf's avatar
   
Alexander Neundorf committed
817
818
819
820
821
822
823
824
}

void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
{
  // use LanguageToLinkerPreference to detect whether this functions has
  // run before
  if (this->LanguageToLinkerPreference.find(l) !=
                                        this->LanguageToLinkerPreference.end())
825
826
827
    {
    return;
    }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
828
829
830
831

  std::string linkerPrefVar = std::string("CMAKE_") +
    std::string(l) + std::string("_LINKER_PREFERENCE");
  const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
832
833
  int preference = 0;
  if(linkerPref)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
834
    {
835
836
837
    if (sscanf(linkerPref, "%d", &preference)!=1)
      {
      // backward compatibility: before 2.6 LINKER_PREFERENCE
838
839
      // was either "None" or "Prefered", and only the first character was
      // tested. So if there is a custom language out there and it is
840
841
842
843
844
845
846
847
848
849
      // "Prefered", set its preference high
      if (linkerPref[0]=='P')
        {
        preference = 100;
        }
      else
        {
        preference = 0;
        }
      }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
850
851
    }

852
853
854
855
856
857
858
859
860
  if (preference < 0)
    {
    std::string msg = linkerPrefVar;
    msg += " is negative, adjusting it to 0";
    cmSystemTools::Message(msg.c_str(), "Warning");
    preference = 0;
    }

  this->LanguageToLinkerPreference[l] = preference;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
861

Alexander Neundorf's avatar
   
Alexander Neundorf committed
862
  std::string outputExtensionVar = std::string("CMAKE_") +
863
864
865
866
    std::string(l) + std::string("_OUTPUT_EXTENSION");
  const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str());
  if(outputExtension)
    {
Ken Martin's avatar
Ken Martin committed
867
868
    this->LanguageToOutputExtension[l] = outputExtension;
    this->OutputExtensions[outputExtension] = outputExtension;
869
870
    if(outputExtension[0] == '.')
      {
Ken Martin's avatar
Ken Martin committed
871
      this->OutputExtensions[outputExtension+1] = outputExtension+1;
872
      }
873
    }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
874

875
876
877
878
879
  // The map was originally filled by SetLanguageEnabledFlag, but
  // since then the compiler- and platform-specific files have been
  // loaded which might have added more entries.
  this->FillExtensionToLanguageMap(l, mf);

Alexander Neundorf's avatar
   
Alexander Neundorf committed
880
  std::string ignoreExtensionsVar = std::string("CMAKE_") +
881
882
    std::string(l) + std::string("_IGNORE_EXTENSIONS");
  std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str());
883
  std::vector<std::string> extensionList;
884
  cmSystemTools::ExpandListArgument(ignoreExts, extensionList);
885
886
887
  for(std::vector<std::string>::iterator i = extensionList.begin();
      i != extensionList.end(); ++i)
    {
888
    this->IgnoreExtensions[*i] = true;
889
    }
890
891
892
893
894
895
896
897
898
899
900

}

void cmGlobalGenerator::FillExtensionToLanguageMap(const char* l,
                                                   cmMakefile* mf)
{
  std::string extensionsVar = std::string("CMAKE_") +
    std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS");
  std::string exts = mf->GetSafeDefinition(extensionsVar.c_str());
  std::vector<std::string> extensionList;
  cmSystemTools::ExpandListArgument(exts, extensionList);
901
902
903
  for(std::vector<std::string>::iterator i = extensionList.begin();
      i != extensionList.end(); ++i)
    {
904
    this->ExtensionToLanguage[*i] = l;
905
    }
Ken Martin's avatar
Ken Martin committed
906
}
Alexander Neundorf's avatar
   
Alexander Neundorf committed
907

908
909
bool cmGlobalGenerator::IgnoreFile(const char* l)
{
910
911
912
913
  if(this->GetLanguageFromExtension(l))
    {
    return false;
    }
Ken Martin's avatar
Ken Martin committed
914
  return (this->IgnoreExtensions.count(l) > 0);
915
}
Ken Martin's avatar
Ken Martin committed
916

Alexander Neundorf's avatar
   
Alexander Neundorf committed
917
bool cmGlobalGenerator::GetLanguageEnabled(const char* l) const
Ken Martin's avatar
Ken Martin committed
918
{
Alexander Neundorf's avatar
   
Alexander Neundorf committed
919
  return (this->LanguageEnabled.find(l)!= this->LanguageEnabled.end());
Ken Martin's avatar
Ken Martin committed
920
921
922
923
}

void cmGlobalGenerator::ClearEnabledLanguages()
{
Ken Martin's avatar
Ken Martin committed
924
  this->LanguageEnabled.clear();
Ken Martin's avatar
Ken Martin committed
925
926
}

927
928
929
930
931
932
933
934
bool cmGlobalGenerator::IsDependedOn(const char* project,
                                     cmTarget* targetIn)
{
  // Get all local gens for this project
  std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
  // loop over local gens and get the targets for each one
  for(unsigned int i = 0; i < gens->size(); ++i)
    {
Alexander Neundorf's avatar
   
Alexander Neundorf committed
935
    cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets();
936
937
    for (cmTargets::iterator l = targets.begin();
         l != targets.end(); l++)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
938
      {
939
      cmTarget& target = l->second;
940
941
      TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
      if(tgtdeps.count(targetIn))
942
943
944
945
946
        {
        return true;
        }
      }
    }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
947
  return false;
948
949
}

Ken Martin's avatar
Ken Martin committed
950
951
void cmGlobalGenerator::Configure()
{
952
  this->FirstTimeProgress = 0.0f;
953
  this->ClearGeneratorMembers();
954

Ken Martin's avatar
Ken Martin committed
955
956
  // start with this directory
  cmLocalGenerator *lg = this->CreateLocalGenerator();
Ken Martin's avatar
Ken Martin committed
957
  this->LocalGenerators.push_back(lg);
Ken Martin's avatar
Ken Martin committed
958
959

  // set the Start directories
960
  cmMakefile* mf = lg->GetMakefile();
961
  lg->GetMakefile()->SetStartDirectory
Ken Martin's avatar
Ken Martin committed
962
    (this->CMakeInstance->GetStartDirectory());
963
  lg->GetMakefile()->SetStartOutputDirectory
Ken Martin's avatar
Ken Martin committed
964
    (this->CMakeInstance->GetStartOutputDirectory());
Ken Martin's avatar
updates    
Ken Martin committed
965
  lg->GetMakefile()->MakeStartDirectoriesCurrent();
Alexander Neundorf's avatar
   
Alexander Neundorf committed
966

967
968
  this->BinaryDirectories.insert(mf->GetStartOutputDirectory());

Ken Martin's avatar
Ken Martin committed
969
  // now do it
970
  lg->Configure();
Alexander Neundorf's avatar
   
Alexander Neundorf committed
971

972
973
974
  // update the cache entry for the number of local generators, this is used
  // for progress
  char num[100];
Ken Martin's avatar
Ken Martin committed
975
  sprintf(num,"%d",static_cast<int>(this->LocalGenerators.size()));
976
977
  this->GetCMakeInstance()->AddCacheEntry
    ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
978
     "number of local generators", cmCacheManager::INTERNAL);
Alexander Neundorf's avatar
   
Alexander Neundorf committed
979

Alexander Neundorf's avatar
   
Alexander Neundorf committed
980
981
982
  // check for link libraries and include directories containing "NOTFOUND"
  // and for infinite loops
  this->CheckLocalGenerators();
Bill Hoffman's avatar
Bill Hoffman committed
983

Ken Martin's avatar
Ken Martin committed
984
  // at this point this->LocalGenerators has been filled,
985
  // so create the map from project name to vector of local generators
986
987
  this->FillProjectMap();

988
  if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
Andy Cedilnik's avatar
Andy Cedilnik committed
989
    {
990
    cmOStringStream msg;
991
992
    if(cmSystemTools::GetErrorOccuredFlag())
      {
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
      msg << "Configuring incomplete, errors occurred!";
      const char* logs[] = {"CMakeOutput.log", "CMakeError.log", 0};
      for(const char** log = logs; *log; ++log)
        {
        std::string f = this->CMakeInstance->GetHomeOutputDirectory();
        f += this->CMakeInstance->GetCMakeFilesDirectory();
        f += "/";
        f += *log;
        if(cmSystemTools::FileExists(f.c_str()))
          {
          msg << "\nSee also \"" << f << "\".";
          }
        }
      }
    else
      {
      msg << "Configuring done";
1010
      }
1011
    this->CMakeInstance->UpdateProgress(msg.str().c_str(), -1);
Andy Cedilnik's avatar
Andy Cedilnik committed
1012
    }
Ken Martin's avatar
Ken Martin committed
1013
1014
}

1015
1016
1017
1018
1019
1020
1021
1022
cmExportBuildFileGenerator*
cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const
{
  std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
    = this->BuildExportSets.find(filename);
  return it == this->BuildExportSets.end() ? 0 : it->second;
}

1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
{
  // If the property is not enabled then okay.
  if(!this->CMakeInstance
     ->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
    {
    return true;
    }

  // This generator does not support duplicate custom targets.
  cmOStringStream e;
  e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
    << "global property.  "
    << "The \"" << this->GetName() << "\" generator does not support "
    << "duplicate custom targets.  "
    << "Consider using a Makefiles generator or fix the project to not "
Stephen Kelly's avatar
Stephen Kelly committed
1039
    << "use duplicate target names.";
1040
1041
1042
1043
  cmSystemTools::Error(e.str().c_str());
  return false;
}

Ken Martin's avatar
Ken Martin committed
1044
1045
void cmGlobalGenerator::Generate()
{
1046
1047
1048
1049
  // Some generators track files replaced during the Generate.
  // Start with an empty vector:
  this->FilesReplacedDuringGenerate.clear();

1050
1051
1052
1053
1054
1055
  // Check whether this generator is allowed to run.
  if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
    {
    return;
    }

1056
1057
1058
1059
1060
1061
  // Check that all targets are valid.
  if(!this->CheckTargets())
    {
    return;
    }

1062
  this->FinalizeTargetCompileInfo();
1063

1064
#ifdef CMAKE_BUILD_WITH_CMAKE
1065
  // Iterate through all targets and set up automoc for those which have
1066
  // the AUTOMOC, AUTOUIC or AUTORCC property set
1067
1068
1069
  AutogensType autogens;
  this->CreateQtAutoGeneratorsTargets(autogens);
#endif
1070

Ken Martin's avatar
Ken Martin committed
1071
  // For each existing cmLocalGenerator
Ken Martin's avatar
Ken Martin committed
1072
  unsigned int i;
1073

1074
  // Put a copy of each global target in every directory.
1075
1076
  cmTargets globalTargets;
  this->CreateDefaultGlobalTargets(&globalTargets);
Ken Martin's avatar
Ken Martin committed
1077
  for (i = 0; i < this->LocalGenerators.size(); ++i)
1078
    {
1079
1080
    cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
    cmTargets* targets = &(mf->GetTargets());
Andy Cedilnik's avatar
Andy Cedilnik committed
1081
1082
1083
    cmTargets::iterator tit;
    for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
      {
1084
      (*targets)[tit->first] = tit->second;
1085
      (*targets)[tit->first].SetMakefile(mf);
Andy Cedilnik's avatar
Andy Cedilnik committed
1086
      }
1087
    }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
1088

1089
1090
1091
1092
1093
1094
  // Add generator specific helper commands
  for (i = 0; i < this->LocalGenerators.size(); ++i)
    {
    this->LocalGenerators[i]->AddHelperCommands();
    }

1095
1096
1097
  // Create per-target generator information.
  this->CreateGeneratorTargets();

1098
1099
1100
1101
1102
1103
1104
1105
#ifdef CMAKE_BUILD_WITH_CMAKE
  for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
       ++it)
    {
    it->first.SetupAutoGenerateTarget(it->second);
    }
#endif

1106