cmMakefile.cxx 22 KB
Newer Older
1
2
3
4
5
6
7
8
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Will Schroeder's avatar
Will Schroeder committed
9
10
Copyright (c) 2001 Insight Consortium
All rights reserved.
11

Will Schroeder's avatar
Will Schroeder committed
12
13
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
14

Will Schroeder's avatar
Will Schroeder committed
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
40

=========================================================================*/
41
#include "cmMakefile.h"
42
#include "cmCommand.h"
43
#include "cmStandardIncludes.h"
44
#include "cmSourceFile.h"
45
#include "cmDirectory.h"
46
#include "cmSystemTools.h"
47
#include "cmMakefileGenerator.h"
48
#include "cmCommands.h"
49
#include "cmCacheManager.h"
50
#include "cmFunctionBlocker.h"
51
52
53
54

// default is not to be building executables
cmMakefile::cmMakefile()
{
55
  // Setup the default include file regular expression.
56
  // Should be changed to something like "\\.(h|hh|hpp|hxx)$" or "^.*$"
57
58
  m_IncludeFileRegularExpression = "^itk|^vtk|^vnl|^vcl|^f2c";
  
59
60
  m_DefineFlags = " ";
  m_MakefileGenerator = 0;
61
62
63
  this->AddSourceGroup("", "^.*$");
  this->AddSourceGroup("Source Files", "\\.(cpp|C|c|cxx|rc|def|r|odl|idl|hpj|bat)$");
  this->AddSourceGroup("Header Files", "\\.(h|hh|hpp|hxx|hm|inl)$");
64
  this->AddDefaultCommands();
65
  this->AddDefaultDefinitions();
66
67
}

68
void cmMakefile::AddDefaultCommands()
69
{
70
71
72
73
74
75
76
  std::list<cmCommand*> commands;
  GetPredefinedCommands(commands);
  for(std::list<cmCommand*>::iterator i = commands.begin();
      i != commands.end(); ++i)
    {
    this->AddCommand(*i);
    }
77
78
79
80
81
#ifdef _WIN32
  this->AddDefinition("WIN32", "1");
#else
  this->AddDefinition("UNIX", "1");
#endif
82
  // Cygwin is more like unix so enable the unix commands
83
84
85
86
87
88
89
90
#if defined(__CYGWIN__)
  this->AddDefinition("UNIX", "1");
#endif
}


cmMakefile::~cmMakefile()
{
91
  for(unsigned int i=0; i < m_UsedCommands.size(); i++)
92
    {
93
    delete m_UsedCommands[i];
94
    }
95
96
  for(RegisteredCommandsMap::iterator j = m_Commands.begin();
      j != m_Commands.end(); ++j)
97
98
99
100
101
102
    {
    delete (*j).second;
    }
  delete m_MakefileGenerator;
}

103
void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>& v) const
104
105
{
  std::cout << s << ": ( \n";
106
  for(std::vector<std::string>::const_iterator i = v.begin();
107
108
109
110
111
      i != v.end(); ++i)
    {
    std::cout << (*i).c_str() << " ";
    }
  std::cout << " )\n";
112
113
114
115
}


// call print on all the classes in the makefile
116
void cmMakefile::Print() const
117
{
118
  // print the class lists
119
  std::cout << "classes:\n";
120
121
  for(SourceMap::const_iterator l = m_Sources.begin(); 
      l != m_Sources.end(); l++)
122
123
    {
    std::cout << " Class list named: " << l->first << std::endl;
124
    for(std::vector<cmSourceFile>::const_iterator i = l->second.begin(); 
125
126
127
128
129
130
131
132
133
134
135
136
137
        i != l->second.end(); i++)
      {
      i->Print();
      }
    }
  
  std::cout << " m_Targets: ";
  for (cmTargets::const_iterator l = m_Targets.begin();
       l != m_Targets.end(); l++)
    {
    std::cout << l->first << std::endl;
    }

Ken Martin's avatar
Ken Martin committed
138
139
140
141
142
143
  std::cout << " m_CurrentOutputDirectory; " << 
    m_CurrentOutputDirectory.c_str() << std::endl;
  std::cout << " m_StartOutputDirectory; " << 
    m_StartOutputDirectory.c_str() << std::endl;
  std::cout << " m_HomeOutputDirectory; " << 
    m_HomeOutputDirectory.c_str() << std::endl;
144
145
  std::cout << " m_cmCurrentDirectory; " << 
    m_cmCurrentDirectory.c_str() << std::endl;
Ken Martin's avatar
Ken Martin committed
146
147
148
149
  std::cout << " m_cmStartDirectory; " << 
    m_cmStartDirectory.c_str() << std::endl;
  std::cout << " m_cmHomeDirectory; " << 
    m_cmHomeDirectory.c_str() << std::endl;
150
151
152
153
154
  std::cout << " m_ProjectName;	" <<  m_ProjectName.c_str() << std::endl;
  this->PrintStringVector("m_SubDirectories ", m_SubDirectories); 
  this->PrintStringVector("m_MakeVerbatim ", m_MakeVerbatim); 
  this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories);
  this->PrintStringVector("m_LinkDirectories", m_LinkDirectories);
155
156
  this->PrintStringVector("m_Utilities", m_Utilities);
  this->PrintStringVector("m_UtilityDirectories", m_UtilityDirectories);
157
158
}

159
// Parse the given CMakeLists.txt file into a list of classes.
Ken Martin's avatar
Ken Martin committed
160
161
162
// Reads in current CMakeLists file and all parent CMakeLists files
// executing all inherited commands in the parents
bool cmMakefile::ReadListFile(const char* filename)
163
{
Ken Martin's avatar
Ken Martin committed
164
165
166
167
  // is there a parent CMakeLists file that does not go beyond the
  // Home directory? if so recurse and read in that List file 
  std::string parentList = this->GetParentListFileName(filename);
  if (parentList != "")
168
    {
Ken Martin's avatar
Ken Martin committed
169
170
171
172
173
174
175
176
177
178
179
    // save the current directory
    std::string srcdir = m_cmCurrentDirectory;
    std::string bindir = m_CurrentOutputDirectory;    
    // compute the new current directories
    std::string::size_type pos = m_cmCurrentDirectory.rfind('/');
    if(pos != std::string::npos)
      {
      m_cmCurrentDirectory = m_cmCurrentDirectory.substr(0, pos);
      }
    pos = m_CurrentOutputDirectory.rfind('/');
    if(pos != std::string::npos)
180
      {
Ken Martin's avatar
Ken Martin committed
181
      m_CurrentOutputDirectory = m_CurrentOutputDirectory.substr(0, pos);
182
      }
Ken Martin's avatar
Ken Martin committed
183
184
185
186
    this->ReadListFile(parentList.c_str());
    // restore the current directory
    m_cmCurrentDirectory = srcdir;
    m_CurrentOutputDirectory = bindir;    
187
    }
Ken Martin's avatar
Ken Martin committed
188
189
190
191
192

  // are we at the start CMakeLists file or are we processing a parent 
  // lists file
  bool inheriting = (m_cmCurrentDirectory != m_cmStartDirectory);
                    
193
  // Now read the input file
194
195
196
  std::ifstream fin(filename);
  if(!fin)
    {
197
    cmSystemTools::Error("error can not open file ", filename);
198
199
    return false;
    }
200
201
202
  std::string name;
  std::vector<std::string> arguments;
  while ( fin )
203
    {
204
205
    if(cmSystemTools::ParseFunction(fin, name, arguments) &&
       !this->IsFunctionBlocked(name.c_str(),arguments))
206
      {
207
208
      // Special command that needs to be removed when 
      // ADD_COMMAND is implemented
209
      if(name == "VERBATIM")
210
        {
Ken Martin's avatar
Ken Martin committed
211
        if (!inheriting)
212
          {
213
214
215
216
217
          m_MakeVerbatim = arguments;
          }
        }
      else
        {
218
219
        RegisteredCommandsMap::iterator pos = m_Commands.find(name);
        if(pos != m_Commands.end())
220
          {
221
222
223
          cmCommand* rm = (*pos).second;
          cmCommand* usedCommand = rm->Clone();
          usedCommand->SetMakefile(this);
224
          bool keepCommand = false;
225
          if(usedCommand->GetEnabled())
226
227
            {
            // if not running in inherit mode or
228
229
            // if the command is inherited then Invoke it.
            if(!inheriting || usedCommand->IsInherited())
230
              {
231
              if(!usedCommand->Invoke(arguments))
232
                {
233
234
                cmSystemTools::Error(usedCommand->GetName(),
                                     ": Error : \n",
235
236
                                     usedCommand->GetError(),
                                     m_cmCurrentDirectory.c_str());
237
                }
238
239
240
241
242
243
              else
                {
                // use the command
                keepCommand = true;
                m_UsedCommands.push_back(usedCommand);
                }
244
245
              }
            }
246
247
248
249
250
251
          // if the Cloned command was not used 
          // then delete it
          if(!keepCommand)
            {
            delete usedCommand;
            }
252
253
254
          }
        else
          {
255
          cmSystemTools::Error("unknown CMake command ", name.c_str());
256
257
          }
        }
258
259
260
261
      }
    }
  return true;
}
262

263
264
  

265
cmSourceFile *cmMakefile::GetSource(const char *srclist, const char *cname)
266
{
267
  SourceMap::iterator sl = m_Sources.find(srclist);
268
  // find the src list
269
  if (sl == m_Sources.end())
270
271
272
273
    {
    return 0;
    }
  // find the class
274
  for (std::vector<cmSourceFile>::iterator i = sl->second.begin();
275
276
       i != sl->second.end(); ++i)
    {
277
    if (i->GetSourceName() == cname)
278
279
280
281
282
283
284
      {
      return &(*i);
      }
    }
  return 0;
}

285
void cmMakefile::AddCommand(cmCommand* wg)
286
287
{
  std::string name = wg->GetName();
288
  m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
289
290
291
292
293
294
295
296
297
298
299
300
301
}

  // Set the make file 
void cmMakefile::SetMakefileGenerator(cmMakefileGenerator* mf)
{
  delete m_MakefileGenerator;
  m_MakefileGenerator = mf;
}

  // Generate the output file
void cmMakefile::GenerateMakefile()
{
  // do all the variable expansions here
302
  this->ExpandVariables();
303
304
  // set the makefile on the generator
  m_MakefileGenerator->SetMakefile(this);
305
  // give all the commands a chance to do something
306
  // after the file has been parsed before generation
307
308
  for(std::vector<cmCommand*>::iterator i = m_UsedCommands.begin();
      i != m_UsedCommands.end(); ++i)
309
310
    {
    (*i)->FinalPass();
311
    }
312
313
  // now do the generation
  m_MakefileGenerator->GenerateMakefile();
314
315
}

316
void cmMakefile::AddSource(cmSourceFile& cmfile, const char *srclist)
317
{
318
  m_Sources[srclist].push_back(cmfile);
319
}
320

321
322
323
void cmMakefile::AddCustomCommand(const char* source,
                                  const char* command,
                                  const std::vector<std::string>& depends,
324
325
                                  const std::vector<std::string>& outputs,
                                  const char *target) 
326
{
327
328
329
330
  // find the target, 
  if (m_Targets.find(target) != m_Targets.end())
    {
    cmCustomCommand cc(source,command,depends,outputs);
331
    m_Targets[target].GetCustomCommands().push_back(cc);
332
    }
333
}
334

335
void cmMakefile::AddCustomCommand(const char* source,
336
337
                                  const char* command,
                                  const std::vector<std::string>& depends,
338
339
                                  const char* output, 
                                  const char *target) 
340
{
341
342
  std::vector<std::string> outputs;
  outputs.push_back(output);
343
  this->AddCustomCommand(source, command, depends, outputs, target);
344
345
346
347
348
349
350
351
}

void cmMakefile::AddDefineFlag(const char* flag)
{
  m_DefineFlags += " ";
  m_DefineFlags += flag;
}

352
353
354
355
356
357
358
359
360
361
void cmMakefile::AddUtility(const char* util)
{
  m_Utilities.push_back(util);
}

void cmMakefile::AddUtilityDirectory(const char* dir)
{
  m_UtilityDirectories.push_back(dir);
}

362
363
364
365
366
367
void cmMakefile::AddLinkLibrary(const char* lib, LinkLibraryType llt)
{
  m_LinkLibraries.push_back(
    std::pair<std::string, LinkLibraryType>(lib,llt));
}

368
369
void cmMakefile::AddLinkLibrary(const char* lib)
{
370
  this->AddLinkLibrary(lib,GENERAL);
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
}

void cmMakefile::AddLinkDirectory(const char* dir)
{
  m_LinkDirectories.push_back(dir);
}

void cmMakefile::AddSubDirectory(const char* sub)
{
  m_SubDirectories.push_back(sub);
}

void cmMakefile::AddIncludeDirectory(const char* inc)
{
  m_IncludeDirectories.push_back(inc);
}

void cmMakefile::AddDefinition(const char* name, const char* value)
{
  m_Definitions.insert(DefinitionMap::value_type(name, value));
}
392
393
394
395
396
397
398
399
400
401
402
void cmMakefile::AddDefinition(const char* name, bool value)
{
  if(value)
    {
    m_Definitions.insert(DefinitionMap::value_type(name, "ON"));
    }
  else
    {
    m_Definitions.insert(DefinitionMap::value_type(name, "OFF"));
    }
}
403
404
405
406
407
408

void cmMakefile::SetProjectName(const char* p)
{
  m_ProjectName = p;
}

409
410
411
void cmMakefile::AddLibrary(const char* lname, const std::vector<std::string> &srcs)
{
  cmTarget target;
412
413
  target.SetIsALibrary(1);
  target.GetSourceLists() = srcs;
414
415
416
417
418
  m_Targets.insert(cmTargets::value_type(lname,target));
}

void cmMakefile::AddExecutable(const char *exeName, 
                               const std::vector<std::string> &srcs)
419
{
420
  cmTarget target;
421
422
  target.SetIsALibrary(0);
  target.GetSourceLists() = srcs;
423
  m_Targets.insert(cmTargets::value_type(exeName,target));
424
425
}

426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
void cmMakefile::AddSourceGroup(const char* name, const char* regex)
{
  // First see if the group exists.  If so, replace its regular expression.
  for(std::vector<cmSourceGroup>::iterator sg = m_SourceGroups.begin();
      sg != m_SourceGroups.end(); ++sg)
    {
    std::string sgName = sg->GetName();
    if(sgName == name)
      {
      // We only want to set the regular expression.  If there are already
      // source files in the group, we don't want to remove them.
      sg->SetGroupRegex(regex);
      return;
      }
    }
  
  // The group doesn't exist.  Add it.
  m_SourceGroups.push_back(cmSourceGroup(name, regex));
}
446
447
448
449
450

void cmMakefile::AddExtraDirectory(const char* dir)
{
  m_AuxSourceDirectories.push_back(dir);
}
451

452

Ken Martin's avatar
Ken Martin committed
453
454
455
456
457
// return the file name for the parent CMakeLists file to the 
// one passed in. Zero is returned if the CMakeLists file is the
// one in the home directory or if for some reason a parent cmake lists 
// file cannot be found.
std::string cmMakefile::GetParentListFileName(const char *currentFileName)
458
{
Ken Martin's avatar
Ken Martin committed
459
460
461
462
463
464
  // extract the directory name
  std::string parentFile;
  std::string listsDir = currentFileName;
  std::string::size_type pos = listsDir.rfind('/');
  // if we could not find the directory return 0
  if(pos == std::string::npos)
465
    {
Ken Martin's avatar
Ken Martin committed
466
    return parentFile;
467
    }
Ken Martin's avatar
Ken Martin committed
468
469
470
471
  listsDir = listsDir.substr(0, pos);
  
  // if we are in the home directory then stop, return 0
  if(m_cmHomeDirectory == listsDir)
472
    {
Ken Martin's avatar
Ken Martin committed
473
    return parentFile;
474
    }
Ken Martin's avatar
Ken Martin committed
475
476
477
478
479
480
481
482
483
484
485
486
487
488
  
  // is there a parent directory we can check
  pos = listsDir.rfind('/');
  // if we could not find the directory return 0
  if(pos == std::string::npos)
    {
    return parentFile;
    }
  listsDir = listsDir.substr(0, pos);
  
  // is there a CMakeLists.txt file in the parent directory ?
  parentFile = listsDir;
  parentFile += "/CMakeLists.txt";
  if(!cmSystemTools::FileExists(parentFile.c_str()))
489
    {
Ken Martin's avatar
Ken Martin committed
490
491
    parentFile = "";
    return parentFile;
492
    }
Ken Martin's avatar
Ken Martin committed
493
494
  
  return parentFile;
495
496
}

497
498
499
// expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
// include and library directories.

500
void cmMakefile::ExpandVariables()
501
{
502
  // Now expand varibles in the include and link strings
503
504
505
506
507
  std::vector<std::string>::iterator j, begin, end;
  begin = m_IncludeDirectories.begin();
  end = m_IncludeDirectories.end();
  for(j = begin; j != end; ++j)
    {
508
    this->ExpandVariablesInString(*j);
509
510
511
512
513
    }
  begin = m_LinkDirectories.begin();
  end = m_LinkDirectories.end();
  for(j = begin; j != end; ++j)
    {
514
515
    this->ExpandVariablesInString(*j);
    }
516
517
518
519
  LinkLibraries::iterator j2, end2;
  j2 = m_LinkLibraries.begin();
  end2 = m_LinkLibraries.end();
  for(; j2 != end2; ++j2)
520
    {
521
    this->ExpandVariablesInString(j2->first);
522
523
524
525
526
527
528
529
530
531
532
533
    }
}

const char* cmMakefile::GetDefinition(const char* name)
{
  DefinitionMap::iterator pos = m_Definitions.find(name);
  if(pos != m_Definitions.end())
    {
    return (*pos).second.c_str();
    }
  return 0;
}
534
535
536
537
538
539
540
541
542
543
544
545

int cmMakefile::DumpDocumentationToFile(const char *fileName)
{
  // Open the supplied filename
  std::ofstream f;
  f.open(fileName, std::ios::out);
  
  if ( f.fail() )
    {
    return 0;
    }
  
546
  // Loop over all registered commands and print out documentation
547
548
549
550
  const char *name;
  const char *terse;
  const char *full;

551
552
  for(RegisteredCommandsMap::iterator j = m_Commands.begin();
      j != m_Commands.end(); ++j)
553
554
    {
    name = (*j).second->GetName();
555
556
    terse = (*j).second->GetTerseDocumentation();
    full = (*j).second->GetFullDocumentation();
557
    f << name << " - " << terse << std::endl
Will Schroeder's avatar
Will Schroeder committed
558
      << "Usage: " << full << std::endl << std::endl;
559
560
561
562
563
564
    }
  

  return 1;
}

565

566
void cmMakefile::ExpandVariablesInString(std::string& source) const
567
{
568
  for(DefinitionMap::const_iterator i = m_Definitions.begin();
569
570
571
572
573
      i != m_Definitions.end(); ++i)
    {
    std::string variable = "${";
    variable += (*i).first;
    variable += "}";
574
575
576
577
578
    cmSystemTools::ReplaceString(source, variable.c_str(),
                                 (*i).second.c_str());
    variable = "@";
    variable += (*i).first;
    variable += "@";
579
580
581
582
583
    cmSystemTools::ReplaceString(source, variable.c_str(),
                                 (*i).second.c_str());
    }
}

Bill Hoffman's avatar
Bill Hoffman committed
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640

// recursive function to create a vector of cmMakefile objects
// This is done by reading the sub directory CMakeLists.txt files,
// then calling this function with the new cmMakefile object
void 
cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>&
                                            makefiles)
{ 
  // loop over all the sub directories of this makefile
  const std::vector<std::string>& subdirs = this->GetSubDirectories();
  for(std::vector<std::string>::const_iterator i = subdirs.begin();
      i != subdirs.end(); ++i)
    {
    std::string subdir = *i;
    // Create a path to the list file in the sub directory
    std::string listFile = this->GetCurrentDirectory();
    listFile += "/";
    listFile += subdir;
    listFile += "/CMakeLists.txt";
    // if there is a CMakeLists.txt file read it
    if(!cmSystemTools::FileExists(listFile.c_str()))
      {
      cmSystemTools::Error("CMakeLists.txt file missing from sub directory:",
                           listFile.c_str());
      }
    else
      {
      cmMakefile* mf = new cmMakefile;
      makefiles.push_back(mf);
      // initialize new makefile
      mf->SetHomeOutputDirectory(this->GetHomeOutputDirectory());
      mf->SetHomeDirectory(this->GetHomeDirectory());
      // add the subdir to the start output directory
      std::string outdir = this->GetStartOutputDirectory();
      outdir += "/";
      outdir += subdir;
      mf->SetStartOutputDirectory(outdir.c_str());
      // add the subdir to the start source directory
      std::string currentDir = this->GetStartDirectory();
      currentDir += "/";
      currentDir += subdir;
      mf->SetStartDirectory(currentDir.c_str());
      // Parse the CMakeLists.txt file
      currentDir += "/CMakeLists.txt";
      mf->MakeStartDirectoriesCurrent();
      mf->ReadListFile(currentDir.c_str());
      // recurse into nextDir
      mf->FindSubDirectoryCMakeListsFiles(makefiles);
      }
    }
}

      
void cmMakefile::GenerateCacheOnly()
{
  std::vector<cmMakefile*> makefiles;
  this->FindSubDirectoryCMakeListsFiles(makefiles);
641
642
643
644
645
646
647
648
649
650
  for(std::vector<cmMakefile*>::iterator i = makefiles.begin();
      i != makefiles.end(); ++i)
    {
    cmMakefile* mf = *i;
    std::string source = mf->GetHomeDirectory();
    source += "/CMake/CMakeMakefileTemplate.in";
    cmSystemTools::MakeDirectory(mf->GetStartOutputDirectory());
    std::string dest = mf->GetStartOutputDirectory();
    dest += "/Makefile";
    std::ofstream fout(dest.c_str());
651
    std::cout << "cmake: creating : " << dest.c_str() << "\n";
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
    if(!fout)
      {
      cmSystemTools::Error("Failed to open file for write " , dest.c_str());
      }
    else
      {
      if(strcmp(mf->GetHomeDirectory(), 
                mf->GetHomeOutputDirectory()) == 0)
        {
        fout << "srcdir        = .\n\n";
        }
      else
        {
        fout << "srcdir        = " <<  mf->GetStartDirectory() << "\n";
        fout << "VPATH         = " <<  mf->GetStartDirectory() << "\n";
        }
      }
    fout << "include "
         << mf->GetHomeOutputDirectory() << "/CMake/CMakeMaster.make\n";
    }
  
673
  for(unsigned int i =0; i < makefiles.size(); ++i)
Bill Hoffman's avatar
Bill Hoffman committed
674
675
676
677
678
679
    {
    delete makefiles[i];
    }
}


680
681
682
683
684
685
686
687
/**
 * Add the default definitions to the makefile.  These values must not
 * be dependent on anything that isn't known when this cmMakefile instance
 * is constructed.
 */
void cmMakefile::AddDefaultDefinitions()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
688
  this->AddDefinition("CMAKE_CFG_OUTDIR","$(OUTDIR)");
689
#else
690
  this->AddDefinition("CMAKE_CFG_OUTDIR",".");
691
692
#endif
}
693
694
695
696
697
698
699
700

/**
 * Find a source group whose regular expression matches the filename
 * part of the given source name.  Search backward through the list of
 * source groups, and take the first matching group found.  This way
 * non-inherited SOURCE_GROUP commands will have precedence over
 * inherited ones.
 */
701
702
703
cmSourceGroup& 
cmMakefile::FindSourceGroup(const char* source,
                            std::vector<cmSourceGroup> &groups)
704
705
706
707
708
709
710
711
{
  std::string file = source;
  std::string::size_type pos = file.rfind('/');
  if(pos != std::string::npos)
    {
    file = file.substr(pos, file.length()-pos);
    }

712
713
  for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
      sg != groups.rend(); ++sg)
714
715
716
717
718
719
720
721
    {
    if(sg->Matches(file.c_str()))
      {
      return *sg;
      }
    }
  
  // Shouldn't get here, but just in case, return the default group.
722
  return groups.front();
723
}
724
725


726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
bool cmMakefile::IsFunctionBlocked(const char *name,
                                   std::vector<std::string> &args) const
{
  // loop over all function blockers to see if any block this command
  std::set<cmFunctionBlocker *>::const_iterator pos;
  for (pos = m_FunctionBlockers.begin(); 
       pos != m_FunctionBlockers.end(); ++pos)
    {
    if ((*pos)->IsFunctionBlocked(name, args, *this))
      {
      return true;
      }
    }
  
  return false;
}

void cmMakefile::RemoveFunctionBlocker(const char *name,
								       const std::vector<std::string> &args)
{
  // loop over all function blockers to see if any block this command
  std::set<cmFunctionBlocker *>::const_iterator pos;
  for (pos = m_FunctionBlockers.begin(); 
       pos != m_FunctionBlockers.end(); ++pos)
    {
    if ((*pos)->ShouldRemove(name, args, *this))
      {
      m_FunctionBlockers.erase(*pos);
      return;
      }
    }
  
  return;
}