Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmLocalUnixMakefileGenerator3.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmLocalUnixMakefileGenerator3.h"
13
14 #include "cmGeneratedFileStream.h"
15 #include "cmGlobalUnixMakefileGenerator3.h"
16 #include "cmMakefile.h"
17 #include "cmMakefileTargetGenerator.h"
18 #include "cmSourceFile.h"
19 #include "cmake.h"
20 #include "cmVersion.h"
21 #include "cmFileTimeComparison.h"
22 #include "cmCustomCommandGenerator.h"
23
24 // Include dependency scanners for supported languages.  Only the
25 // C/C++ scanner is needed for bootstrapping CMake.
26 #include "cmDependsC.h"
27 #ifdef CMAKE_BUILD_WITH_CMAKE
28 # include "cmDependsFortran.h"
29 # include "cmDependsJava.h"
30 # include <cmsys/Terminal.h>
31 #endif
32
33 #include <cmsys/auto_ptr.hxx>
34
35 #include <memory> // auto_ptr
36 #include <queue>
37
38 //----------------------------------------------------------------------------
39 // Escape special characters in Makefile dependency lines
40 class cmMakeSafe
41 {
42 public:
43   cmMakeSafe(const char* s): Data(s) {}
44   cmMakeSafe(std::string const& s): Data(s.c_str()) {}
45 private:
46   const char* Data;
47   friend std::ostream& operator<<(std::ostream& os,
48                                   cmMakeSafe const& self)
49     {
50     for(const char* c = self.Data; *c; ++c)
51       {
52       switch (*c)
53         {
54         case '=': os << "$(EQUALS)"; break;
55         default: os << *c; break;
56         }
57       }
58     return os;
59     }
60 };
61
62 //----------------------------------------------------------------------------
63 // Helper function used below.
64 static std::string cmSplitExtension(std::string const& in, std::string& base)
65 {
66   std::string ext;
67   std::string::size_type dot_pos = in.rfind(".");
68   if(dot_pos != std::string::npos)
69     {
70     // Remove the extension first in case &base == &in.
71     ext = in.substr(dot_pos, std::string::npos);
72     base = in.substr(0, dot_pos);
73     }
74   else
75     {
76     base = in;
77     }
78   return ext;
79 }
80
81 //----------------------------------------------------------------------------
82 cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
83 {
84   this->SilentNoColon = false;
85   this->WindowsShell = false;
86   this->IncludeDirective = "include";
87   this->MakefileVariableSize = 0;
88   this->IgnoreLibPrefix = false;
89   this->PassMakeflags = false;
90   this->DefineWindowsNULL = false;
91   this->UnixCD = true;
92   this->ColorMakefile = false;
93   this->SkipPreprocessedSourceRules = false;
94   this->SkipAssemblySourceRules = false;
95   this->MakeCommandEscapeTargetTwice = false;
96   this->IsMakefileGenerator = true;
97   this->BorlandMakeCurlyHack = false;
98 }
99
100 //----------------------------------------------------------------------------
101 cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3()
102 {
103 }
104
105 //----------------------------------------------------------------------------
106 void cmLocalUnixMakefileGenerator3::Configure()
107 {
108   // Compute the path to use when referencing the current output
109   // directory from the top output directory.
110   this->HomeRelativeOutputPath =
111     this->Convert(this->Makefile->GetStartOutputDirectory(), HOME_OUTPUT);
112   if(this->HomeRelativeOutputPath == ".")
113     {
114     this->HomeRelativeOutputPath = "";
115     }
116   if(!this->HomeRelativeOutputPath.empty())
117     {
118     this->HomeRelativeOutputPath += "/";
119     }
120   this->cmLocalGenerator::Configure();
121 }
122
123 //----------------------------------------------------------------------------
124 void cmLocalUnixMakefileGenerator3::Generate()
125 {
126   // Store the configuration name that will be generated.
127   if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
128     {
129     // Use the build type given by the user.
130     this->ConfigurationName = config;
131     }
132   else
133     {
134     // No configuration type given.
135     this->ConfigurationName = "";
136     }
137
138   // Record whether some options are enabled to avoid checking many
139   // times later.
140   if(!this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile())
141     {
142     this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
143     }
144   this->SkipPreprocessedSourceRules =
145     this->Makefile->IsOn("CMAKE_SKIP_PREPROCESSED_SOURCE_RULES");
146   this->SkipAssemblySourceRules =
147     this->Makefile->IsOn("CMAKE_SKIP_ASSEMBLY_SOURCE_RULES");
148
149   // Generate the rule files for each target.
150   cmTargets& targets = this->Makefile->GetTargets();
151   cmGlobalUnixMakefileGenerator3* gg =
152     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
153   for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
154     {
155     cmsys::auto_ptr<cmMakefileTargetGenerator> tg(
156       cmMakefileTargetGenerator::New(&(t->second)));
157     if (tg.get())
158       {
159       tg->WriteRuleFiles();
160       gg->RecordTargetProgress(tg.get());
161       }
162     }
163
164   // write the local Makefile
165   this->WriteLocalMakefile();
166
167   // Write the cmake file with information for this directory.
168   this->WriteDirectoryInformationFile();
169 }
170
171 //----------------------------------------------------------------------------
172 void cmLocalUnixMakefileGenerator3::AddLocalObjectFile(
173   cmTarget* target, cmSourceFile* sf, std::string objNoTargetDir,
174   bool hasSourceExtension)
175 {
176   if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str()))
177     {
178     objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir);
179     }
180   LocalObjectInfo& info = this->LocalObjectFiles[objNoTargetDir];
181   info.HasSourceExtension = hasSourceExtension;
182   info.push_back(LocalObjectEntry(target, sf->GetLanguage()));
183 }
184
185 //----------------------------------------------------------------------------
186 void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets
187                                             (std::vector<std::string>& targets)
188 {
189   for (std::map<cmStdString, LocalObjectInfo>::iterator lo =
190          this->LocalObjectFiles.begin();
191        lo != this->LocalObjectFiles.end(); ++lo)
192     {
193     targets.push_back(lo->first);
194
195     std::string::size_type dot_pos = lo->first.rfind(".");
196     std::string base = lo->first.substr(0, dot_pos);
197     if(lo->second.HasPreprocessRule)
198       {
199       targets.push_back(base + ".i");
200       }
201
202     if(lo->second.HasAssembleRule)
203       {
204       targets.push_back(base + ".s");
205       }
206     }
207 }
208
209 //----------------------------------------------------------------------------
210 void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
211 {
212   // generate the includes
213   std::string ruleFileName = "Makefile";
214
215   // Open the rule file.  This should be copy-if-different because the
216   // rules may depend on this file itself.
217   std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
218   cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
219   if(!ruleFileStream)
220     {
221     return;
222     }
223   // always write the top makefile
224   if (this->Parent)
225     {
226     ruleFileStream.SetCopyIfDifferent(true);
227     }
228
229   // write the all rules
230   this->WriteLocalAllRules(ruleFileStream);
231
232   // only write local targets unless at the top Keep track of targets already
233   // listed.
234   std::set<cmStdString> emittedTargets;
235   if (this->Parent)
236     {
237     // write our targets, and while doing it collect up the object
238     // file rules
239     this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets);
240     }
241   else
242     {
243     cmGlobalUnixMakefileGenerator3 *gg =
244       static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
245     gg->WriteConvenienceRules(ruleFileStream,emittedTargets);
246     }
247
248   bool do_preprocess_rules =
249     this->GetCreatePreprocessedSourceRules();
250   bool do_assembly_rules =
251     this->GetCreateAssemblySourceRules();
252
253   // now write out the object rules
254   // for each object file name
255   for (std::map<cmStdString, LocalObjectInfo>::iterator lo =
256          this->LocalObjectFiles.begin();
257        lo != this->LocalObjectFiles.end(); ++lo)
258     {
259     // Add a convenience rule for building the object file.
260     this->WriteObjectConvenienceRule(ruleFileStream,
261                                      "target to build an object file",
262                                      lo->first.c_str(), lo->second);
263
264     // Check whether preprocessing and assembly rules make sense.
265     // They make sense only for C and C++ sources.
266     bool lang_is_c_or_cxx = false;
267     for(std::vector<LocalObjectEntry>::const_iterator ei =
268           lo->second.begin(); ei != lo->second.end(); ++ei)
269       {
270       if(ei->Language == "C" || ei->Language == "CXX")
271         {
272         lang_is_c_or_cxx = true;
273         break;
274         }
275       }
276
277     // Add convenience rules for preprocessed and assembly files.
278     if(lang_is_c_or_cxx && (do_preprocess_rules || do_assembly_rules))
279       {
280       std::string::size_type dot_pos = lo->first.rfind(".");
281       std::string base = lo->first.substr(0, dot_pos);
282       if(do_preprocess_rules)
283         {
284         this->WriteObjectConvenienceRule(
285           ruleFileStream, "target to preprocess a source file",
286           (base + ".i").c_str(), lo->second);
287           lo->second.HasPreprocessRule = true;
288         }
289       if(do_assembly_rules)
290         {
291         this->WriteObjectConvenienceRule(
292           ruleFileStream, "target to generate assembly for a file",
293           (base + ".s").c_str(), lo->second);
294           lo->second.HasAssembleRule = true;
295         }
296       }
297     }
298
299   // add a help target as long as there isn;t a real target named help
300   if(emittedTargets.insert("help").second)
301     {
302     cmGlobalUnixMakefileGenerator3 *gg =
303       static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
304     gg->WriteHelpRule(ruleFileStream,this);
305     }
306
307   this->WriteSpecialTargetsBottom(ruleFileStream);
308 }
309
310 //----------------------------------------------------------------------------
311 void
312 cmLocalUnixMakefileGenerator3
313 ::WriteObjectConvenienceRule(std::ostream& ruleFileStream,
314                              const char* comment, const char* output,
315                              LocalObjectInfo const& info)
316 {
317   // If the rule includes the source file extension then create a
318   // version that has the extension removed.  The help should include
319   // only the version without source extension.
320   bool inHelp = true;
321   if(info.HasSourceExtension)
322     {
323     // Remove the last extension.  This should be kept.
324     std::string outBase1 = output;
325     std::string outExt1 = cmSplitExtension(outBase1, outBase1);
326
327     // Now remove the source extension and put back the last
328     // extension.
329     std::string outNoExt;
330     cmSplitExtension(outBase1, outNoExt);
331     outNoExt += outExt1;
332
333     // Add a rule to drive the rule below.
334     std::vector<std::string> depends;
335     depends.push_back(output);
336     std::vector<std::string> no_commands;
337     this->WriteMakeRule(ruleFileStream, 0,
338                         outNoExt.c_str(), depends, no_commands, true, true);
339     inHelp = false;
340     }
341
342   // Recursively make the rule for each target using the object file.
343   std::vector<std::string> commands;
344   for(std::vector<LocalObjectEntry>::const_iterator t = info.begin();
345       t != info.end(); ++t)
346     {
347     std::string tgtMakefileName =
348       this->GetRelativeTargetDirectory(*(t->Target));
349     std::string targetName = tgtMakefileName;
350     tgtMakefileName += "/build.make";
351     targetName += "/";
352     targetName += output;
353     commands.push_back(
354       this->GetRecursiveMakeCall(tgtMakefileName.c_str(), targetName.c_str())
355       );
356     }
357   this->CreateCDCommand(commands,
358                         this->Makefile->GetHomeOutputDirectory(),
359                         cmLocalGenerator::START_OUTPUT);
360
361   // Write the rule to the makefile.
362   std::vector<std::string> no_depends;
363   this->WriteMakeRule(ruleFileStream, comment,
364                       output, no_depends, commands, true, inHelp);
365 }
366
367 //----------------------------------------------------------------------------
368 void cmLocalUnixMakefileGenerator3
369 ::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
370                             std::set<cmStdString> &emitted)
371 {
372   std::vector<std::string> depends;
373   std::vector<std::string> commands;
374
375   // for each target we just provide a rule to cd up to the top and do a make
376   // on the target
377   cmTargets& targets = this->Makefile->GetTargets();
378   std::string localName;
379   for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
380     {
381     if((t->second.GetType() == cmTarget::EXECUTABLE) ||
382        (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
383        (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
384        (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
385        (t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
386        (t->second.GetType() == cmTarget::UTILITY))
387       {
388       emitted.insert(t->second.GetName());
389
390       // for subdirs add a rule to build this specific target by name.
391       localName = this->GetRelativeTargetDirectory(t->second);
392       localName += "/rule";
393       commands.clear();
394       depends.clear();
395
396       // Build the target for this pass.
397       std::string makefile2 = cmake::GetCMakeFilesDirectoryPostSlash();
398       makefile2 += "Makefile2";
399       commands.push_back(this->GetRecursiveMakeCall
400                          (makefile2.c_str(),localName.c_str()));
401       this->CreateCDCommand(commands,
402                             this->Makefile->GetHomeOutputDirectory(),
403                             cmLocalGenerator::START_OUTPUT);
404       this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
405                           localName.c_str(), depends, commands, true);
406
407       // Add a target with the canonical name (no prefix, suffix or path).
408       if(localName != t->second.GetName())
409         {
410         commands.clear();
411         depends.push_back(localName);
412         this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
413                             t->second.GetName(), depends, commands, true);
414         }
415
416       // Add a fast rule to build the target
417       std::string makefileName = this->GetRelativeTargetDirectory(t->second);
418       makefileName += "/build.make";
419       // make sure the makefile name is suitable for a makefile
420       std::string makeTargetName =
421         this->GetRelativeTargetDirectory(t->second);
422       makeTargetName += "/build";
423       localName = t->second.GetName();
424       localName += "/fast";
425       depends.clear();
426       commands.clear();
427       commands.push_back(this->GetRecursiveMakeCall
428                          (makefileName.c_str(), makeTargetName.c_str()));
429       this->CreateCDCommand(commands,
430                             this->Makefile->GetHomeOutputDirectory(),
431                             cmLocalGenerator::START_OUTPUT);
432       this->WriteMakeRule(ruleFileStream, "fast build rule for target.",
433                           localName.c_str(), depends, commands, true);
434
435       // Add a local name for the rule to relink the target before
436       // installation.
437       if(t->second.NeedRelinkBeforeInstall(this->ConfigurationName.c_str()))
438         {
439         makeTargetName = this->GetRelativeTargetDirectory(t->second);
440         makeTargetName += "/preinstall";
441         localName = t->second.GetName();
442         localName += "/preinstall";
443         depends.clear();
444         commands.clear();
445         commands.push_back(this->GetRecursiveMakeCall
446                            (makefile2.c_str(), makeTargetName.c_str()));
447         this->CreateCDCommand(commands,
448                               this->Makefile->GetHomeOutputDirectory(),
449                               cmLocalGenerator::START_OUTPUT);
450         this->WriteMakeRule(ruleFileStream,
451                             "Manual pre-install relink rule for target.",
452                             localName.c_str(), depends, commands, true);
453         }
454       }
455     }
456 }
457
458 //----------------------------------------------------------------------------
459 void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
460 {
461   std::string infoFileName = this->Makefile->GetStartOutputDirectory();
462   infoFileName += cmake::GetCMakeFilesDirectory();
463   infoFileName += "/CMakeDirectoryInformation.cmake";
464
465   // Open the output file.
466   cmGeneratedFileStream infoFileStream(infoFileName.c_str());
467   if(!infoFileStream)
468     {
469     return;
470     }
471
472   infoFileStream.SetCopyIfDifferent(true);
473   // Write the do not edit header.
474   this->WriteDisclaimer(infoFileStream);
475
476   // Setup relative path conversion tops.
477   infoFileStream
478     << "# Relative path conversion top directories.\n"
479     << "SET(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" << this->RelativePathTopSource
480     << "\")\n"
481     << "SET(CMAKE_RELATIVE_PATH_TOP_BINARY \"" << this->RelativePathTopBinary
482     << "\")\n"
483     << "\n";
484
485   // Tell the dependency scanner to use unix paths if necessary.
486   if(cmSystemTools::GetForceUnixPaths())
487     {
488     infoFileStream
489       << "# Force unix paths in dependencies.\n"
490       << "SET(CMAKE_FORCE_UNIX_PATHS 1)\n"
491       << "\n";
492     }
493
494   // Store the include regular expressions for this directory.
495   infoFileStream
496     << "\n"
497     << "# The C and CXX include file regular expressions for "
498     << "this directory.\n";
499   infoFileStream
500     << "SET(CMAKE_C_INCLUDE_REGEX_SCAN ";
501   this->WriteCMakeArgument(infoFileStream,
502                            this->Makefile->GetIncludeRegularExpression());
503   infoFileStream
504     << ")\n";
505   infoFileStream
506     << "SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN ";
507   this->WriteCMakeArgument(infoFileStream,
508                            this->Makefile->GetComplainRegularExpression());
509   infoFileStream
510     << ")\n";
511   infoFileStream
512     << "SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n";
513   infoFileStream
514     << "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN "
515     "${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n";
516 }
517
518 //----------------------------------------------------------------------------
519 std::string
520 cmLocalUnixMakefileGenerator3
521 ::ConvertToFullPath(const std::string& localPath)
522 {
523   std::string dir = this->Makefile->GetStartOutputDirectory();
524   dir += "/";
525   dir += localPath;
526   return dir;
527 }
528
529
530 const std::string &cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
531 {
532   return this->HomeRelativeOutputPath;
533 }
534
535
536 //----------------------------------------------------------------------------
537 void
538 cmLocalUnixMakefileGenerator3
539 ::WriteMakeRule(std::ostream& os,
540                 const char* comment,
541                 const char* target,
542                 const std::vector<std::string>& depends,
543                 const std::vector<std::string>& commands,
544                 bool symbolic,
545                 bool in_help)
546 {
547   // Make sure there is a target.
548   if(!target || !*target)
549     {
550     cmSystemTools::Error("No target for WriteMakeRule! called with comment: ",
551                          comment);
552     return;
553     }
554
555   std::string replace;
556
557   // Write the comment describing the rule in the makefile.
558   if(comment)
559     {
560     replace = comment;
561     std::string::size_type lpos = 0;
562     std::string::size_type rpos;
563     while((rpos = replace.find('\n', lpos)) != std::string::npos)
564       {
565       os << "# " << replace.substr(lpos, rpos-lpos) << "\n";
566       lpos = rpos+1;
567       }
568     os << "# " << replace.substr(lpos) << "\n";
569     }
570
571   // Construct the left hand side of the rule.
572   replace = target;
573   std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
574   const char* space = "";
575   if(tgt.size() == 1)
576     {
577     // Add a space before the ":" to avoid drive letter confusion on
578     // Windows.
579     space = " ";
580     }
581
582   // Mark the rule as symbolic if requested.
583   if(symbolic)
584     {
585     if(const char* sym =
586        this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE"))
587       {
588       os << cmMakeSafe(tgt) << space << ": " << sym << "\n";
589       }
590     }
591
592   // Write the rule.
593   if(depends.empty())
594     {
595     // No dependencies.  The commands will always run.
596     os << cmMakeSafe(tgt) << space << ":\n";
597     }
598   else
599     {
600     // Split dependencies into multiple rule lines.  This allows for
601     // very long dependency lists even on older make implementations.
602     for(std::vector<std::string>::const_iterator dep = depends.begin();
603         dep != depends.end(); ++dep)
604       {
605       replace = *dep;
606       replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
607       os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
608       }
609     }
610
611   // Write the list of commands.
612   for(std::vector<std::string>::const_iterator i = commands.begin();
613       i != commands.end(); ++i)
614     {
615     replace = *i;
616     os << "\t" << replace.c_str() << "\n";
617     }
618   if(symbolic && !this->WatcomWMake)
619     {
620     os << ".PHONY : " << cmMakeSafe(tgt) << "\n";
621     }
622   os << "\n";
623   // Add the output to the local help if requested.
624   if(in_help)
625     {
626     this->LocalHelp.push_back(target);
627     }
628 }
629
630 //----------------------------------------------------------------------------
631 std::string
632 cmLocalUnixMakefileGenerator3
633 ::ConvertShellCommand(std::string const& cmd, RelativeRoot root)
634 {
635   if(this->WatcomWMake &&
636      cmSystemTools::FileIsFullPath(cmd.c_str()) &&
637      cmd.find_first_of("( )") != cmd.npos)
638     {
639     // On Watcom WMake use the windows short path for the command
640     // name.  This is needed to avoid funny quoting problems on
641     // lines with shell redirection operators.
642     std::string scmd;
643     if(cmSystemTools::GetShortPath(cmd.c_str(), scmd))
644       {
645       return this->Convert(scmd.c_str(), NONE, SHELL);
646       }
647     }
648   return this->Convert(cmd.c_str(), root, SHELL);
649 }
650
651 //----------------------------------------------------------------------------
652 void
653 cmLocalUnixMakefileGenerator3
654 ::WriteMakeVariables(std::ostream& makefileStream)
655 {
656   this->WriteDivider(makefileStream);
657   makefileStream
658     << "# Set environment variables for the build.\n"
659     << "\n";
660   if(this->DefineWindowsNULL)
661     {
662     makefileStream
663       << "!IF \"$(OS)\" == \"Windows_NT\"\n"
664       << "NULL=\n"
665       << "!ELSE\n"
666       << "NULL=nul\n"
667       << "!ENDIF\n";
668     }
669   if(this->WindowsShell)
670     {
671      makefileStream
672        << "SHELL = cmd.exe\n"
673        << "\n";
674     }
675   else
676     {
677 #if !defined(__VMS)
678       makefileStream
679         << "# The shell in which to execute make rules.\n"
680         << "SHELL = /bin/sh\n"
681         << "\n";
682 #endif
683     }
684
685   std::string cmakecommand =
686       this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
687   makefileStream
688     << "# The CMake executable.\n"
689     << "CMAKE_COMMAND = "
690     << this->ConvertShellCommand(cmakecommand, FULL)
691     << "\n"
692     << "\n";
693   makefileStream
694     << "# The command to remove a file.\n"
695     << "RM = "
696     << this->ConvertShellCommand(cmakecommand, FULL)
697     << " -E remove -f\n"
698     << "\n";
699   makefileStream
700     << "# Escaping for special characters.\n"
701     << "EQUALS = =\n"
702     << "\n";
703
704   if(const char* edit_cmd =
705      this->Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
706     {
707     makefileStream
708       << "# The program to use to edit the cache.\n"
709       << "CMAKE_EDIT_COMMAND = "
710       << this->ConvertShellCommand(edit_cmd, FULL) << "\n"
711       << "\n";
712     }
713
714   makefileStream
715     << "# The top-level source directory on which CMake was run.\n"
716     << "CMAKE_SOURCE_DIR = "
717     << this->Convert(this->Makefile->GetHomeDirectory(), FULL, SHELL)
718     << "\n"
719     << "\n";
720   makefileStream
721     << "# The top-level build directory on which CMake was run.\n"
722     << "CMAKE_BINARY_DIR = "
723     << this->Convert(this->Makefile->GetHomeOutputDirectory(), FULL, SHELL)
724     << "\n"
725     << "\n";
726 }
727
728 //----------------------------------------------------------------------------
729 void
730 cmLocalUnixMakefileGenerator3
731 ::WriteSpecialTargetsTop(std::ostream& makefileStream)
732 {
733   this->WriteDivider(makefileStream);
734   makefileStream
735     << "# Special targets provided by cmake.\n"
736     << "\n";
737
738   std::vector<std::string> no_commands;
739   std::vector<std::string> no_depends;
740
741   // Special target to cleanup operation of make tool.
742   // This should be the first target except for the default_target in
743   // the interface Makefile.
744   this->WriteMakeRule(
745     makefileStream, "Disable implicit rules so canonical targets will work.",
746     ".SUFFIXES", no_depends, no_commands, false);
747
748   if(!this->NMake && !this->WatcomWMake && !this->BorlandMakeCurlyHack)
749     {
750     // turn off RCS and SCCS automatic stuff from gmake
751     makefileStream
752       << "# Remove some rules from gmake that .SUFFIXES does not remove.\n"
753       << "SUFFIXES =\n\n";
754     }
755   // Add a fake suffix to keep HP happy.  Must be max 32 chars for SGI make.
756   std::vector<std::string> depends;
757   depends.push_back(".hpux_make_needs_suffix_list");
758   this->WriteMakeRule(makefileStream, 0,
759                       ".SUFFIXES", depends, no_commands, false);
760
761   cmGlobalUnixMakefileGenerator3* gg =
762     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
763   // Write special target to silence make output.  This must be after
764   // the default target in case VERBOSE is set (which changes the
765   // name).  The setting of CMAKE_VERBOSE_MAKEFILE to ON will cause a
766   // "VERBOSE=1" to be added as a make variable which will change the
767   // name of this special target.  This gives a make-time choice to
768   // the user.
769   if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
770     {
771     makefileStream
772       << "# Produce verbose output by default.\n"
773       << "VERBOSE = 1\n"
774       << "\n";
775     }
776   if(this->SilentNoColon)
777     {
778     makefileStream << "$(VERBOSE).SILENT\n";
779     }
780   else
781     {
782     this->WriteMakeRule(makefileStream,
783                         "Suppress display of executed commands.",
784                         "$(VERBOSE).SILENT",
785                         no_depends,
786                         no_commands, false);
787     }
788
789   // Work-around for makes that drop rules that have no dependencies
790   // or commands.
791   std::string hack = gg->GetEmptyRuleHackDepends();
792   if(!hack.empty())
793     {
794     no_depends.push_back(hack);
795     }
796   std::string hack_cmd = gg->GetEmptyRuleHackCommand();
797   if(!hack_cmd.empty())
798     {
799     no_commands.push_back(hack_cmd);
800     }
801
802   // Special symbolic target that never exists to force dependers to
803   // run their rules.
804   this->WriteMakeRule
805     (makefileStream,
806      "A target that is always out of date.",
807      "cmake_force", no_depends, no_commands, true);
808
809   // Variables for reference by other rules.
810   this->WriteMakeVariables(makefileStream);
811 }
812
813 //----------------------------------------------------------------------------
814 void cmLocalUnixMakefileGenerator3
815 ::WriteSpecialTargetsBottom(std::ostream& makefileStream)
816 {
817   this->WriteDivider(makefileStream);
818   makefileStream
819     << "# Special targets to cleanup operation of make.\n"
820     << "\n";
821
822   // Write special "cmake_check_build_system" target to run cmake with
823   // the --check-build-system flag.
824   {
825   // Build command to run CMake to check if anything needs regenerating.
826   std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
827   cmakefileName += "Makefile.cmake";
828   std::string runRule =
829     "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
830   runRule += " --check-build-system ";
831   runRule += this->Convert(cmakefileName.c_str(),NONE,SHELL);
832   runRule += " 0";
833
834   std::vector<std::string> no_depends;
835   std::vector<std::string> commands;
836   commands.push_back(runRule);
837   if(this->Parent)
838     {
839     this->CreateCDCommand(commands,
840                           this->Makefile->GetHomeOutputDirectory(),
841                           cmLocalGenerator::START_OUTPUT);
842     }
843   this->WriteMakeRule(makefileStream,
844                       "Special rule to run CMake to check the build system "
845                       "integrity.\n"
846                       "No rule that depends on this can have "
847                       "commands that come from listfiles\n"
848                       "because they might be regenerated.",
849                       "cmake_check_build_system",
850                       no_depends,
851                       commands, true);
852   }
853 }
854
855
856
857 //----------------------------------------------------------------------------
858 void
859 cmLocalUnixMakefileGenerator3
860 ::WriteConvenienceRule(std::ostream& ruleFileStream,
861                        const char* realTarget,
862                        const char* helpTarget)
863 {
864   // A rule is only needed if the names are different.
865   if(strcmp(realTarget, helpTarget) != 0)
866     {
867     // The helper target depends on the real target.
868     std::vector<std::string> depends;
869     depends.push_back(realTarget);
870
871     // There are no commands.
872     std::vector<std::string> no_commands;
873
874     // Write the rule.
875     this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
876                         helpTarget, depends, no_commands, true);
877     }
878 }
879
880
881 //----------------------------------------------------------------------------
882 std::string
883 cmLocalUnixMakefileGenerator3
884 ::GetRelativeTargetDirectory(cmTarget const& target)
885 {
886   std::string dir = this->HomeRelativeOutputPath;
887   dir += this->GetTargetDirectory(target);
888   return this->Convert(dir.c_str(),NONE,UNCHANGED);
889 }
890
891
892
893 //----------------------------------------------------------------------------
894 void cmLocalUnixMakefileGenerator3::AppendFlags(std::string& flags,
895                                                 const char* newFlags)
896 {
897   if(this->WatcomWMake && newFlags && *newFlags)
898     {
899     std::string newf = newFlags;
900     if(newf.find("\\\"") != newf.npos)
901       {
902       cmSystemTools::ReplaceString(newf, "\\\"", "\"");
903       this->cmLocalGenerator::AppendFlags(flags, newf.c_str());
904       return;
905       }
906     }
907   this->cmLocalGenerator::AppendFlags(flags, newFlags);
908 }
909
910 //----------------------------------------------------------------------------
911 void
912 cmLocalUnixMakefileGenerator3
913 ::AppendRuleDepend(std::vector<std::string>& depends,
914                    const char* ruleFileName)
915 {
916   // Add a dependency on the rule file itself unless an option to skip
917   // it is specifically enabled by the user or project.
918   const char* nodep =
919     this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
920   if(!nodep || cmSystemTools::IsOff(nodep))
921     {
922     depends.push_back(ruleFileName);
923     }
924 }
925
926 //----------------------------------------------------------------------------
927 void
928 cmLocalUnixMakefileGenerator3
929 ::AppendRuleDepends(std::vector<std::string>& depends,
930                     std::vector<std::string> const& ruleFiles)
931 {
932   // Add a dependency on the rule file itself unless an option to skip
933   // it is specifically enabled by the user or project.
934   if(!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY"))
935     {
936     depends.insert(depends.end(), ruleFiles.begin(), ruleFiles.end());
937     }
938 }
939
940 //----------------------------------------------------------------------------
941 void
942 cmLocalUnixMakefileGenerator3
943 ::AppendCustomDepends(std::vector<std::string>& depends,
944                       const std::vector<cmCustomCommand>& ccs)
945 {
946   for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
947       i != ccs.end(); ++i)
948     {
949     this->AppendCustomDepend(depends, *i);
950     }
951 }
952
953 //----------------------------------------------------------------------------
954 void
955 cmLocalUnixMakefileGenerator3
956 ::AppendCustomDepend(std::vector<std::string>& depends,
957                      const cmCustomCommand& cc)
958 {
959   for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
960       d != cc.GetDepends().end(); ++d)
961     {
962     // Lookup the real name of the dependency in case it is a CMake target.
963     std::string dep;
964     if(this->GetRealDependency(d->c_str(), this->ConfigurationName.c_str(),
965                                dep))
966       {
967       depends.push_back(dep);
968       }
969     }
970 }
971
972 //----------------------------------------------------------------------------
973 void
974 cmLocalUnixMakefileGenerator3
975 ::AppendCustomCommands(std::vector<std::string>& commands,
976                        const std::vector<cmCustomCommand>& ccs,
977                        cmTarget* target,
978                        cmLocalGenerator::RelativeRoot relative)
979 {
980   for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
981       i != ccs.end(); ++i)
982     {
983     this->AppendCustomCommand(commands, *i, target, true, relative);
984     }
985 }
986
987 //----------------------------------------------------------------------------
988 void
989 cmLocalUnixMakefileGenerator3
990 ::AppendCustomCommand(std::vector<std::string>& commands,
991                       const cmCustomCommand& cc,
992                       cmTarget* target,
993                       bool echo_comment,
994                       cmLocalGenerator::RelativeRoot relative,
995                       std::ostream* content)
996 {
997   // Optionally create a command to display the custom command's
998   // comment text.  This is used for pre-build, pre-link, and
999   // post-build command comments.  Custom build step commands have
1000   // their comments generated elsewhere.
1001   if(echo_comment)
1002     {
1003     const char* comment = cc.GetComment();
1004     if(comment && *comment)
1005       {
1006       this->AppendEcho(commands, comment,
1007                        cmLocalUnixMakefileGenerator3::EchoGenerate);
1008       }
1009     }
1010
1011   // if the command specified a working directory use it.
1012   const char* dir  = this->Makefile->GetStartOutputDirectory();
1013   const char* workingDir = cc.GetWorkingDirectory();
1014   if(workingDir)
1015     {
1016     dir = workingDir;
1017     }
1018   if(content)
1019     {
1020     *content << dir;
1021     }
1022   cmCustomCommandGenerator ccg(cc, this->ConfigurationName.c_str(),
1023                                this->Makefile);
1024
1025   // Add each command line to the set of commands.
1026   std::vector<std::string> commands1;
1027   for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
1028     {
1029     // Build the command line in a single string.
1030     std::string cmd = ccg.GetCommand(c);
1031     if (cmd.size())
1032       {
1033       // Use "call " before any invocations of .bat or .cmd files
1034       // invoked as custom commands in the WindowsShell.
1035       //
1036       bool useCall = false;
1037
1038       if (this->WindowsShell)
1039         {
1040         std::string suffix;
1041         if (cmd.size() > 4)
1042           {
1043           suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size()-4));
1044           if (suffix == ".bat" || suffix == ".cmd")
1045             {
1046             useCall = true;
1047             }
1048           }
1049         }
1050
1051       cmSystemTools::ReplaceString(cmd, "/./", "/");
1052       // Convert the command to a relative path only if the current
1053       // working directory will be the start-output directory.
1054       bool had_slash = cmd.find("/") != cmd.npos;
1055       if(!workingDir)
1056         {
1057         cmd = this->Convert(cmd.c_str(),START_OUTPUT);
1058         }
1059       bool has_slash = cmd.find("/") != cmd.npos;
1060       if(had_slash && !has_slash)
1061         {
1062         // This command was specified as a path to a file in the
1063         // current directory.  Add a leading "./" so it can run
1064         // without the current directory being in the search path.
1065         cmd = "./" + cmd;
1066         }
1067       std::string launcher =
1068         this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT);
1069       cmd = launcher + this->ConvertShellCommand(cmd, NONE);
1070
1071       ccg.AppendArguments(c, cmd);
1072       if(content)
1073         {
1074         // Rule content does not include the launcher.
1075         *content << (cmd.c_str()+launcher.size());
1076         }
1077       if(this->BorlandMakeCurlyHack)
1078         {
1079         // Borland Make has a very strange bug.  If the first curly
1080         // brace anywhere in the command string is a left curly, it
1081         // must be written {{} instead of just {.  Otherwise some
1082         // curly braces are removed.  The hack can be skipped if the
1083         // first curly brace is the last character.
1084         std::string::size_type lcurly = cmd.find("{");
1085         if(lcurly != cmd.npos && lcurly < (cmd.size()-1))
1086           {
1087           std::string::size_type rcurly = cmd.find("}");
1088           if(rcurly == cmd.npos || rcurly > lcurly)
1089             {
1090             // The first curly is a left curly.  Use the hack.
1091             std::string hack_cmd = cmd.substr(0, lcurly);
1092             hack_cmd += "{{}";
1093             hack_cmd += cmd.substr(lcurly+1);
1094             cmd = hack_cmd;
1095             }
1096           }
1097         }
1098       if (launcher.empty())
1099         {
1100         if (useCall)
1101           {
1102           cmd = "call " + cmd;
1103           }
1104         else if (this->NMake && cmd[0]=='"')
1105           {
1106           cmd = "echo >nul && " + cmd;
1107           }
1108         }
1109       commands1.push_back(cmd);
1110       }
1111     }
1112
1113   // Setup the proper working directory for the commands.
1114   this->CreateCDCommand(commands1, dir, relative);
1115
1116   // push back the custom commands
1117   commands.insert(commands.end(), commands1.begin(), commands1.end());
1118 }
1119
1120 //----------------------------------------------------------------------------
1121 std::string
1122 cmLocalUnixMakefileGenerator3::MakeLauncher(const cmCustomCommand& cc,
1123                                             cmTarget* target,
1124                                             RelativeRoot relative)
1125 {
1126   // Short-circuit if there is no launcher.
1127   const char* prop = "RULE_LAUNCH_CUSTOM";
1128   const char* val = this->GetRuleLauncher(target, prop);
1129   if(!(val && *val))
1130     {
1131     return "";
1132     }
1133
1134   // Expand rules in the empty string.  It may insert the launcher and
1135   // perform replacements.
1136   RuleVariables vars;
1137   vars.RuleLauncher = prop;
1138   vars.CMTarget = target;
1139   std::string output;
1140   const std::vector<std::string>& outputs = cc.GetOutputs();
1141   if(!outputs.empty())
1142     {
1143     output = this->Convert(outputs[0].c_str(), relative, SHELL);
1144     }
1145   vars.Output = output.c_str();
1146
1147   std::string launcher;
1148   this->ExpandRuleVariables(launcher, vars);
1149   if(!launcher.empty())
1150     {
1151     launcher += " ";
1152     }
1153   return launcher;
1154 }
1155
1156 //----------------------------------------------------------------------------
1157 void
1158 cmLocalUnixMakefileGenerator3
1159 ::AppendCleanCommand(std::vector<std::string>& commands,
1160                      const std::vector<std::string>& files,
1161                      cmTarget& target, const char* filename)
1162 {
1163   if(!files.empty())
1164     {
1165     std::string cleanfile = this->Makefile->GetCurrentOutputDirectory();
1166     cleanfile += "/";
1167     cleanfile += this->GetTargetDirectory(target);
1168     cleanfile += "/cmake_clean";
1169     if(filename)
1170       {
1171       cleanfile += "_";
1172       cleanfile += filename;
1173       }
1174     cleanfile += ".cmake";
1175     std::string cleanfilePath = this->Convert(cleanfile.c_str(), FULL);
1176     std::ofstream fout(cleanfilePath.c_str());
1177     if(!fout)
1178       {
1179       cmSystemTools::Error("Could not create ", cleanfilePath.c_str());
1180       }
1181     fout << "FILE(REMOVE_RECURSE\n";
1182     std::string remove = "$(CMAKE_COMMAND) -P ";
1183     remove += this->Convert(cleanfile.c_str(), START_OUTPUT, SHELL);
1184     for(std::vector<std::string>::const_iterator f = files.begin();
1185         f != files.end(); ++f)
1186       {
1187       std::string fc = this->Convert(f->c_str(),START_OUTPUT,UNCHANGED);
1188       fout << "  " << this->EscapeForCMake(fc.c_str()) << "\n";
1189       }
1190     fout << ")\n";
1191     commands.push_back(remove);
1192
1193     // For the main clean rule add per-language cleaning.
1194     if(!filename)
1195       {
1196       // Get the set of source languages in the target.
1197       std::set<cmStdString> languages;
1198       target.GetLanguages(languages);
1199       fout << "\n"
1200            << "# Per-language clean rules from dependency scanning.\n"
1201            << "FOREACH(lang";
1202       for(std::set<cmStdString>::const_iterator l = languages.begin();
1203           l != languages.end(); ++l)
1204         {
1205         fout << " " << *l;
1206         }
1207       fout << ")\n"
1208            << "  INCLUDE(" << this->GetTargetDirectory(target)
1209            << "/cmake_clean_${lang}.cmake OPTIONAL)\n"
1210            << "ENDFOREACH(lang)\n";
1211       }
1212     }
1213 }
1214
1215 //----------------------------------------------------------------------------
1216 void
1217 cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
1218                                           const char* text,
1219                                           EchoColor color)
1220 {
1221   // Choose the color for the text.
1222   std::string color_name;
1223 #ifdef CMAKE_BUILD_WITH_CMAKE
1224   if(this->GlobalGenerator->GetToolSupportsColor() && this->ColorMakefile)
1225     {
1226     // See cmake::ExecuteEchoColor in cmake.cxx for these options.
1227     // This color set is readable on both black and white backgrounds.
1228     switch(color)
1229       {
1230       case EchoNormal:
1231         break;
1232       case EchoDepend:
1233         color_name = "--magenta --bold ";
1234         break;
1235       case EchoBuild:
1236         color_name = "--green ";
1237         break;
1238       case EchoLink:
1239         color_name = "--red --bold ";
1240         break;
1241       case EchoGenerate:
1242         color_name = "--blue --bold ";
1243         break;
1244       case EchoGlobal:
1245         color_name = "--cyan ";
1246         break;
1247       }
1248     }
1249 #else
1250   (void)color;
1251 #endif
1252
1253   // Echo one line at a time.
1254   std::string line;
1255   line.reserve(200);
1256   for(const char* c = text;; ++c)
1257     {
1258     if(*c == '\n' || *c == '\0')
1259       {
1260       // Avoid writing a blank last line on end-of-string.
1261       if(*c != '\0' || !line.empty())
1262         {
1263         // Add a command to echo this line.
1264         std::string cmd;
1265         if(color_name.empty())
1266           {
1267           // Use the native echo command.
1268           cmd = "@echo ";
1269           cmd += this->EscapeForShell(line.c_str(), false, true);
1270           }
1271         else
1272           {
1273           // Use cmake to echo the text in color.
1274           cmd = "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) ";
1275           cmd += color_name;
1276           cmd += this->EscapeForShell(line.c_str());
1277           }
1278         commands.push_back(cmd);
1279         }
1280
1281       // Reset the line to emtpy.
1282       line = "";
1283
1284       // Terminate on end-of-string.
1285       if(*c == '\0')
1286         {
1287         return;
1288         }
1289       }
1290     else if(*c != '\r')
1291       {
1292       // Append this character to the current line.
1293       line += *c;
1294       }
1295     }
1296 }
1297
1298 //----------------------------------------------------------------------------
1299 std::string
1300 cmLocalUnixMakefileGenerator3
1301 ::CreateMakeVariable(const char* sin, const char* s2in)
1302 {
1303   std::string s = sin;
1304   std::string s2 = s2in;
1305   std::string unmodified = s;
1306   unmodified += s2;
1307   // if there is no restriction on the length of make variables
1308   // and there are no "." charactors in the string, then return the
1309   // unmodified combination.
1310   if((!this->MakefileVariableSize && unmodified.find('.') == s.npos)
1311      && (!this->MakefileVariableSize && unmodified.find('+') == s.npos)
1312      && (!this->MakefileVariableSize && unmodified.find('-') == s.npos))
1313     {
1314     return unmodified;
1315     }
1316
1317   // see if the variable has been defined before and return
1318   // the modified version of the variable
1319   std::map<cmStdString, cmStdString>::iterator i =
1320     this->MakeVariableMap.find(unmodified);
1321   if(i != this->MakeVariableMap.end())
1322     {
1323     return i->second;
1324     }
1325   // start with the unmodified variable
1326   std::string ret = unmodified;
1327   // if this there is no value for this->MakefileVariableSize then
1328   // the string must have bad characters in it
1329   if(!this->MakefileVariableSize)
1330     {
1331     cmSystemTools::ReplaceString(ret, ".", "_");
1332     cmSystemTools::ReplaceString(ret, "-", "__");
1333     cmSystemTools::ReplaceString(ret, "+", "___");
1334     int ni = 0;
1335     char buffer[5];
1336     // make sure the _ version is not already used, if
1337     // it is used then add number to the end of the variable
1338     while(this->ShortMakeVariableMap.count(ret) && ni < 1000)
1339       {
1340       ++ni;
1341       sprintf(buffer, "%04d", ni);
1342       ret = unmodified + buffer;
1343       }
1344     this->ShortMakeVariableMap[ret] = "1";
1345     this->MakeVariableMap[unmodified] = ret;
1346     return ret;
1347     }
1348
1349   // if the string is greater the 32 chars it is an invalid vairable name
1350   // for borland make
1351   if(static_cast<int>(ret.size()) > this->MakefileVariableSize)
1352     {
1353     int keep = this->MakefileVariableSize - 8;
1354     int size = keep + 3;
1355     std::string str1 = s;
1356     std::string str2 = s2;
1357     // we must shorten the combined string by 4 charactors
1358     // keep no more than 24 charactors from the second string
1359     if(static_cast<int>(str2.size()) > keep)
1360       {
1361       str2 = str2.substr(0, keep);
1362       }
1363     if(static_cast<int>(str1.size()) + static_cast<int>(str2.size()) > size)
1364       {
1365       str1 = str1.substr(0, size - str2.size());
1366       }
1367     char buffer[5];
1368     int ni = 0;
1369     sprintf(buffer, "%04d", ni);
1370     ret = str1 + str2 + buffer;
1371     while(this->ShortMakeVariableMap.count(ret) && ni < 1000)
1372       {
1373       ++ni;
1374       sprintf(buffer, "%04d", ni);
1375       ret = str1 + str2 + buffer;
1376       }
1377     if(ni == 1000)
1378       {
1379       cmSystemTools::Error("Borland makefile variable length too long");
1380       return unmodified;
1381       }
1382     // once an unused variable is found
1383     this->ShortMakeVariableMap[ret] = "1";
1384     }
1385   // always make an entry into the unmodified to variable map
1386   this->MakeVariableMap[unmodified] = ret;
1387   return ret;
1388 }
1389
1390 //----------------------------------------------------------------------------
1391 bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
1392                                                        bool verbose,
1393                                                        bool color)
1394 {
1395   // read in the target info file
1396   if(!this->Makefile->ReadListFile(0, tgtInfo) ||
1397      cmSystemTools::GetErrorOccuredFlag())
1398     {
1399     cmSystemTools::Error("Target DependInfo.cmake file not found");
1400     }
1401
1402   // Check if any multiple output pairs have a missing file.
1403   this->CheckMultipleOutputs(verbose);
1404
1405   std::string dir = cmSystemTools::GetFilenamePath(tgtInfo);
1406   std::string internalDependFile = dir + "/depend.internal";
1407   std::string dependFile = dir + "/depend.make";
1408
1409   // If the target DependInfo.cmake file has changed since the last
1410   // time dependencies were scanned then force rescanning.  This may
1411   // happen when a new source file is added and CMake regenerates the
1412   // project but no other sources were touched.
1413   bool needRescanDependInfo = false;
1414   cmFileTimeComparison* ftc =
1415     this->GlobalGenerator->GetCMakeInstance()->GetFileComparison();
1416   {
1417   int result;
1418   if(!ftc->FileTimeCompare(internalDependFile.c_str(), tgtInfo, &result) ||
1419      result < 0)
1420     {
1421     if(verbose)
1422       {
1423       cmOStringStream msg;
1424       msg << "Dependee \"" << tgtInfo
1425           << "\" is newer than depender \""
1426           << internalDependFile << "\"." << std::endl;
1427       cmSystemTools::Stdout(msg.str().c_str());
1428       }
1429     needRescanDependInfo = true;
1430     }
1431   }
1432
1433   // If the directory information is newer than depend.internal, include dirs
1434   // may have changed. In this case discard all old dependencies.
1435   bool needRescanDirInfo = false;
1436   std::string dirInfoFile = this->Makefile->GetStartOutputDirectory();
1437   dirInfoFile += cmake::GetCMakeFilesDirectory();
1438   dirInfoFile += "/CMakeDirectoryInformation.cmake";
1439   {
1440   int result;
1441   if(!ftc->FileTimeCompare(internalDependFile.c_str(),
1442                            dirInfoFile.c_str(), &result) || result < 0)
1443     {
1444     if(verbose)
1445       {
1446       cmOStringStream msg;
1447       msg << "Dependee \"" << dirInfoFile
1448           << "\" is newer than depender \""
1449           << internalDependFile << "\"." << std::endl;
1450       cmSystemTools::Stdout(msg.str().c_str());
1451       }
1452     needRescanDirInfo = true;
1453     }
1454   }
1455
1456   // Check the implicit dependencies to see if they are up to date.
1457   // The build.make file may have explicit dependencies for the object
1458   // files but these will not affect the scanning process so they need
1459   // not be considered.
1460   std::map<std::string, cmDepends::DependencyVector> validDependencies;
1461   bool needRescanDependencies = false;
1462   if (needRescanDirInfo == false)
1463     {
1464     cmDependsC checker;
1465     checker.SetVerbose(verbose);
1466     checker.SetFileComparison(ftc);
1467     // cmDependsC::Check() fills the vector validDependencies() with the
1468     // dependencies for those files where they are still valid, i.e. neither
1469     // the files themselves nor any files they depend on have changed.
1470     // We don't do that if the CMakeDirectoryInformation.cmake file has
1471     // changed, because then potentially all dependencies have changed.
1472     // This information is given later on to cmDependsC, which then only
1473     // rescans the files where it did not get valid dependencies via this
1474     // dependency vector. This means that in the normal case, when only
1475     // few or one file have been edited, then also only this one file is
1476     // actually scanned again, instead of all files for this target.
1477     needRescanDependencies = !checker.Check(dependFile.c_str(),
1478                                             internalDependFile.c_str(),
1479                                             validDependencies);
1480     }
1481
1482   if(needRescanDependInfo || needRescanDirInfo || needRescanDependencies)
1483     {
1484     // The dependencies must be regenerated.
1485     std::string targetName = cmSystemTools::GetFilenameName(dir);
1486     targetName = targetName.substr(0, targetName.length()-4);
1487     std::string message = "Scanning dependencies of target ";
1488     message += targetName;
1489 #ifdef CMAKE_BUILD_WITH_CMAKE
1490     cmSystemTools::MakefileColorEcho(
1491       cmsysTerminal_Color_ForegroundMagenta |
1492       cmsysTerminal_Color_ForegroundBold,
1493       message.c_str(), true, color);
1494 #else
1495     fprintf(stdout, "%s\n", message.c_str());
1496 #endif
1497
1498     return this->ScanDependencies(dir.c_str(), validDependencies);
1499     }
1500
1501   // The dependencies are already up-to-date.
1502   return true;
1503 }
1504
1505 //----------------------------------------------------------------------------
1506 bool
1507 cmLocalUnixMakefileGenerator3
1508 ::ScanDependencies(const char* targetDir,
1509                  std::map<std::string, cmDepends::DependencyVector>& validDeps)
1510 {
1511   // Read the directory information file.
1512   cmMakefile* mf = this->Makefile;
1513   bool haveDirectoryInfo = false;
1514   std::string dirInfoFile = this->Makefile->GetStartOutputDirectory();
1515   dirInfoFile += cmake::GetCMakeFilesDirectory();
1516   dirInfoFile += "/CMakeDirectoryInformation.cmake";
1517   if(mf->ReadListFile(0, dirInfoFile.c_str()) &&
1518      !cmSystemTools::GetErrorOccuredFlag())
1519     {
1520     haveDirectoryInfo = true;
1521     }
1522
1523   // Lookup useful directory information.
1524   if(haveDirectoryInfo)
1525     {
1526     // Test whether we need to force Unix paths.
1527     if(const char* force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS"))
1528       {
1529       if(!cmSystemTools::IsOff(force))
1530         {
1531         cmSystemTools::SetForceUnixPaths(true);
1532         }
1533       }
1534
1535     // Setup relative path top directories.
1536     this->RelativePathsConfigured = true;
1537     if(const char* relativePathTopSource =
1538        mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
1539       {
1540       this->RelativePathTopSource = relativePathTopSource;
1541       }
1542     if(const char* relativePathTopBinary =
1543        mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
1544       {
1545       this->RelativePathTopBinary = relativePathTopBinary;
1546       }
1547     }
1548   else
1549     {
1550     cmSystemTools::Error("Directory Information file not found");
1551     }
1552
1553   // create the file stream for the depends file
1554   std::string dir = targetDir;
1555
1556   // Open the make depends file.  This should be copy-if-different
1557   // because the make tool may try to reload it needlessly otherwise.
1558   std::string ruleFileNameFull = dir;
1559   ruleFileNameFull += "/depend.make";
1560   cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
1561   ruleFileStream.SetCopyIfDifferent(true);
1562   if(!ruleFileStream)
1563     {
1564     return false;
1565     }
1566
1567   // Open the cmake dependency tracking file.  This should not be
1568   // copy-if-different because dependencies are re-scanned when it is
1569   // older than the DependInfo.cmake.
1570   std::string internalRuleFileNameFull = dir;
1571   internalRuleFileNameFull += "/depend.internal";
1572   cmGeneratedFileStream
1573     internalRuleFileStream(internalRuleFileNameFull.c_str());
1574   if(!internalRuleFileStream)
1575     {
1576     return false;
1577     }
1578
1579   this->WriteDisclaimer(ruleFileStream);
1580   this->WriteDisclaimer(internalRuleFileStream);
1581
1582   // for each language we need to scan, scan it
1583   const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES");
1584   std::vector<std::string> langs;
1585   cmSystemTools::ExpandListArgument(langStr, langs);
1586   for (std::vector<std::string>::iterator li =
1587          langs.begin(); li != langs.end(); ++li)
1588     {
1589     // construct the checker
1590     std::string lang = li->c_str();
1591
1592     // Create the scanner for this language
1593     cmDepends *scanner = 0;
1594     if(lang == "C" || lang == "CXX" || lang == "RC" || lang == "ASM")
1595       {
1596       // TODO: Handle RC (resource files) dependencies correctly.
1597       scanner = new cmDependsC(this, targetDir, lang.c_str(), &validDeps);
1598       }
1599 #ifdef CMAKE_BUILD_WITH_CMAKE
1600     else if(lang == "Fortran")
1601       {
1602       scanner = new cmDependsFortran(this);
1603       }
1604     else if(lang == "Java")
1605       {
1606       scanner = new cmDependsJava();
1607       }
1608 #endif
1609
1610     if (scanner)
1611       {
1612       scanner->SetLocalGenerator(this);
1613       scanner->SetFileComparison
1614         (this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
1615       scanner->SetLanguage(lang.c_str());
1616       scanner->SetTargetDirectory(dir.c_str());
1617       scanner->Write(ruleFileStream, internalRuleFileStream);
1618
1619       // free the scanner for this language
1620       delete scanner;
1621       }
1622     }
1623
1624   return true;
1625 }
1626
1627 //----------------------------------------------------------------------------
1628 void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
1629 {
1630   cmMakefile* mf = this->Makefile;
1631
1632   // Get the string listing the multiple output pairs.
1633   const char* pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS");
1634   if(!pairs_string)
1635     {
1636     return;
1637     }
1638
1639   // Convert the string to a list and preserve empty entries.
1640   std::vector<std::string> pairs;
1641   cmSystemTools::ExpandListArgument(pairs_string, pairs, true);
1642   for(std::vector<std::string>::const_iterator i = pairs.begin();
1643       i != pairs.end() && (i+1) != pairs.end();)
1644     {
1645     const std::string& depender = *i++;
1646     const std::string& dependee = *i++;
1647
1648     // If the depender is missing then delete the dependee to make
1649     // sure both will be regenerated.
1650     if(cmSystemTools::FileExists(dependee.c_str()) &&
1651        !cmSystemTools::FileExists(depender.c_str()))
1652       {
1653       if(verbose)
1654         {
1655         cmOStringStream msg;
1656         msg << "Deleting primary custom command output \"" << dependee
1657             << "\" because another output \""
1658             << depender << "\" does not exist." << std::endl;
1659         cmSystemTools::Stdout(msg.str().c_str());
1660         }
1661       cmSystemTools::RemoveFile(dependee.c_str());
1662       }
1663     }
1664 }
1665
1666 //----------------------------------------------------------------------------
1667 void cmLocalUnixMakefileGenerator3
1668 ::WriteLocalAllRules(std::ostream& ruleFileStream)
1669 {
1670   this->WriteDisclaimer(ruleFileStream);
1671
1672   // Write the main entry point target.  This must be the VERY first
1673   // target so that make with no arguments will run it.
1674   {
1675   // Just depend on the all target to drive the build.
1676   std::vector<std::string> depends;
1677   std::vector<std::string> no_commands;
1678   depends.push_back("all");
1679
1680   // Write the rule.
1681   this->WriteMakeRule(ruleFileStream,
1682                       "Default target executed when no arguments are "
1683                       "given to make.",
1684                       "default_target",
1685                       depends,
1686                       no_commands, true);
1687   }
1688
1689   this->WriteSpecialTargetsTop(ruleFileStream);
1690
1691   // Include the progress variables for the target.
1692   // Write all global targets
1693   this->WriteDivider(ruleFileStream);
1694   ruleFileStream
1695     << "# Targets provided globally by CMake.\n"
1696     << "\n";
1697   cmTargets* targets = &(this->Makefile->GetTargets());
1698   cmTargets::iterator glIt;
1699   for ( glIt = targets->begin(); glIt != targets->end(); ++ glIt )
1700     {
1701     if ( glIt->second.GetType() == cmTarget::GLOBAL_TARGET )
1702       {
1703       std::string targetString = "Special rule for the target " + glIt->first;
1704       std::vector<std::string> commands;
1705       std::vector<std::string> depends;
1706
1707       const char* text = glIt->second.GetProperty("EchoString");
1708       if ( !text )
1709         {
1710         text = "Running external command ...";
1711         }
1712       std::set<cmStdString>::const_iterator dit;
1713       for ( dit = glIt->second.GetUtilities().begin();
1714          dit != glIt->second.GetUtilities().end();
1715         ++ dit )
1716         {
1717         depends.push_back(dit->c_str());
1718         }
1719       this->AppendEcho(commands, text,
1720                        cmLocalUnixMakefileGenerator3::EchoGlobal);
1721
1722       // Global targets store their rules in pre- and post-build commands.
1723       this->AppendCustomDepends(depends,
1724                                 glIt->second.GetPreBuildCommands());
1725       this->AppendCustomDepends(depends,
1726                                 glIt->second.GetPostBuildCommands());
1727       this->AppendCustomCommands(commands,
1728                                  glIt->second.GetPreBuildCommands(),
1729                                  &glIt->second,
1730                                  cmLocalGenerator::START_OUTPUT);
1731       this->AppendCustomCommands(commands,
1732                                  glIt->second.GetPostBuildCommands(),
1733                                  &glIt->second,
1734                                  cmLocalGenerator::START_OUTPUT);
1735       std::string targetName = glIt->second.GetName();
1736       this->WriteMakeRule(ruleFileStream, targetString.c_str(),
1737                           targetName.c_str(), depends, commands, true);
1738
1739       // Provide a "/fast" version of the target.
1740       depends.clear();
1741       if((targetName == "install")
1742           || (targetName == "install_local")
1743           || (targetName == "install_strip"))
1744         {
1745         // Provide a fast install target that does not depend on all
1746         // but has the same command.
1747         depends.push_back("preinstall/fast");
1748         }
1749       else
1750         {
1751         // Just forward to the real target so at least it will work.
1752         depends.push_back(targetName);
1753         commands.clear();
1754         }
1755       targetName += "/fast";
1756       this->WriteMakeRule(ruleFileStream, targetString.c_str(),
1757                           targetName.c_str(), depends, commands, true);
1758       }
1759     }
1760
1761   std::vector<std::string> depends;
1762   std::vector<std::string> commands;
1763
1764   // Write the all rule.
1765   std::string dir;
1766   std::string recursiveTarget = this->Makefile->GetStartOutputDirectory();
1767   recursiveTarget += "/all";
1768
1769   depends.push_back("cmake_check_build_system");
1770
1771   std::string progressDir = this->Makefile->GetHomeOutputDirectory();
1772   progressDir += cmake::GetCMakeFilesDirectory();
1773     {
1774     cmOStringStream progCmd;
1775     progCmd <<
1776       "$(CMAKE_COMMAND) -E cmake_progress_start ";
1777     progCmd << this->Convert(progressDir.c_str(),
1778                              cmLocalGenerator::FULL,
1779                              cmLocalGenerator::SHELL);
1780
1781     std::string progressFile = cmake::GetCMakeFilesDirectory();
1782     progressFile += "/progress.marks";
1783     std::string progressFileNameFull =
1784       this->ConvertToFullPath(progressFile.c_str());
1785     progCmd << " " << this->Convert(progressFileNameFull.c_str(),
1786                                     cmLocalGenerator::FULL,
1787                                     cmLocalGenerator::SHELL);
1788     commands.push_back(progCmd.str());
1789     }
1790   std::string mf2Dir = cmake::GetCMakeFilesDirectoryPostSlash();
1791   mf2Dir += "Makefile2";
1792   commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(),
1793                                                 recursiveTarget.c_str()));
1794   this->CreateCDCommand(commands,
1795                         this->Makefile->GetHomeOutputDirectory(),
1796                         cmLocalGenerator::START_OUTPUT);
1797     {
1798     cmOStringStream progCmd;
1799     progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
1800     progCmd << this->Convert(progressDir.c_str(),
1801                              cmLocalGenerator::FULL,
1802                              cmLocalGenerator::SHELL);
1803     progCmd << " 0";
1804     commands.push_back(progCmd.str());
1805     }
1806   this->WriteMakeRule(ruleFileStream, "The main all target", "all",
1807                       depends, commands, true);
1808
1809   // Write the clean rule.
1810   recursiveTarget = this->Makefile->GetStartOutputDirectory();
1811   recursiveTarget += "/clean";
1812   commands.clear();
1813   depends.clear();
1814   commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(),
1815                                                 recursiveTarget.c_str()));
1816   this->CreateCDCommand(commands,
1817                                 this->Makefile->GetHomeOutputDirectory(),
1818                                 cmLocalGenerator::START_OUTPUT);
1819   this->WriteMakeRule(ruleFileStream, "The main clean target", "clean",
1820                       depends, commands, true);
1821   commands.clear();
1822   depends.clear();
1823   depends.push_back("clean");
1824   this->WriteMakeRule(ruleFileStream, "The main clean target", "clean/fast",
1825                       depends, commands, true);
1826
1827   // Write the preinstall rule.
1828   recursiveTarget = this->Makefile->GetStartOutputDirectory();
1829   recursiveTarget += "/preinstall";
1830   commands.clear();
1831   depends.clear();
1832   const char* noall =
1833     this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
1834   if(!noall || cmSystemTools::IsOff(noall))
1835     {
1836     // Drive the build before installing.
1837     depends.push_back("all");
1838     }
1839   else
1840     {
1841     // At least make sure the build system is up to date.
1842     depends.push_back("cmake_check_build_system");
1843     }
1844   commands.push_back
1845     (this->GetRecursiveMakeCall(mf2Dir.c_str(), recursiveTarget.c_str()));
1846   this->CreateCDCommand(commands,
1847                         this->Makefile->GetHomeOutputDirectory(),
1848                         cmLocalGenerator::START_OUTPUT);
1849   this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
1850                       "preinstall", depends, commands, true);
1851   depends.clear();
1852   this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
1853                       "preinstall/fast", depends, commands, true);
1854
1855   // write the depend rule, really a recompute depends rule
1856   depends.clear();
1857   commands.clear();
1858   std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
1859   cmakefileName += "Makefile.cmake";
1860   std::string runRule =
1861     "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
1862   runRule += " --check-build-system ";
1863   runRule += this->Convert(cmakefileName.c_str(),cmLocalGenerator::NONE,
1864                            cmLocalGenerator::SHELL);
1865   runRule += " 1";
1866   commands.push_back(runRule);
1867   this->CreateCDCommand(commands,
1868                         this->Makefile->GetHomeOutputDirectory(),
1869                         cmLocalGenerator::START_OUTPUT);
1870   this->WriteMakeRule(ruleFileStream, "clear depends",
1871                       "depend",
1872                       depends, commands, true);
1873 }
1874
1875
1876 //----------------------------------------------------------------------------
1877 void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
1878                                                       bool verbose)
1879 {
1880   // Get the list of target files to check
1881   const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES");
1882   if(!infoDef)
1883     {
1884     return;
1885     }
1886   std::vector<std::string> files;
1887   cmSystemTools::ExpandListArgument(infoDef, files);
1888
1889   // Each depend information file corresponds to a target.  Clear the
1890   // dependencies for that target.
1891   cmDepends clearer;
1892   clearer.SetVerbose(verbose);
1893   for(std::vector<std::string>::iterator l = files.begin();
1894       l != files.end(); ++l)
1895     {
1896     std::string dir = cmSystemTools::GetFilenamePath(l->c_str());
1897
1898     // Clear the implicit dependency makefile.
1899     std::string dependFile = dir + "/depend.make";
1900     clearer.Clear(dependFile.c_str());
1901
1902     // Remove the internal dependency check file to force
1903     // regeneration.
1904     std::string internalDependFile = dir + "/depend.internal";
1905     cmSystemTools::RemoveFile(internalDependFile.c_str());
1906     }
1907 }
1908
1909
1910 void cmLocalUnixMakefileGenerator3
1911 ::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)
1912 {
1913   ImplicitDependLanguageMap const& implicitLangs =
1914     this->GetImplicitDepends(target);
1915
1916   // list the languages
1917   cmakefileStream
1918     << "# The set of languages for which implicit dependencies are needed:\n";
1919   cmakefileStream
1920     << "SET(CMAKE_DEPENDS_LANGUAGES\n";
1921   for(ImplicitDependLanguageMap::const_iterator
1922         l = implicitLangs.begin(); l != implicitLangs.end(); ++l)
1923     {
1924     cmakefileStream << "  \"" << l->first.c_str() << "\"\n";
1925     }
1926   cmakefileStream << "  )\n";
1927
1928   // now list the files for each language
1929   cmakefileStream
1930     << "# The set of files for implicit dependencies of each language:\n";
1931   for(ImplicitDependLanguageMap::const_iterator
1932         l = implicitLangs.begin(); l != implicitLangs.end(); ++l)
1933     {
1934     cmakefileStream
1935       << "SET(CMAKE_DEPENDS_CHECK_" << l->first.c_str() << "\n";
1936     ImplicitDependFileMap const& implicitPairs = l->second;
1937
1938     // for each file pair
1939     for(ImplicitDependFileMap::const_iterator pi = implicitPairs.begin();
1940         pi != implicitPairs.end(); ++pi)
1941       {
1942       cmakefileStream << "  \"" << pi->second << "\" ";
1943       cmakefileStream << "\"" << pi->first << "\"\n";
1944       }
1945     cmakefileStream << "  )\n";
1946
1947     // Tell the dependency scanner what compiler is used.
1948     std::string cidVar = "CMAKE_";
1949     cidVar += l->first;
1950     cidVar += "_COMPILER_ID";
1951     const char* cid = this->Makefile->GetDefinition(cidVar.c_str());
1952     if(cid && *cid)
1953       {
1954       cmakefileStream
1955         << "SET(CMAKE_" << l->first.c_str() << "_COMPILER_ID \""
1956         << cid << "\")\n";
1957       }
1958     }
1959
1960   // Build a list of preprocessor definitions for the target.
1961   std::vector<std::string> defines;
1962   {
1963   std::string defPropName = "COMPILE_DEFINITIONS_";
1964   defPropName += cmSystemTools::UpperCase(this->ConfigurationName);
1965   if(const char* ddefs = this->Makefile->GetProperty("COMPILE_DEFINITIONS"))
1966     {
1967     cmSystemTools::ExpandListArgument(ddefs, defines);
1968     }
1969   if(const char* cdefs = target.GetProperty("COMPILE_DEFINITIONS"))
1970     {
1971     cmSystemTools::ExpandListArgument(cdefs, defines);
1972     }
1973   if(const char* dcdefs = this->Makefile->GetProperty(defPropName.c_str()))
1974     {
1975     cmSystemTools::ExpandListArgument(dcdefs, defines);
1976     }
1977   if(const char* ccdefs = target.GetProperty(defPropName.c_str()))
1978     {
1979     cmSystemTools::ExpandListArgument(ccdefs, defines);
1980     }
1981   }
1982   if(!defines.empty())
1983     {
1984     cmakefileStream
1985       << "\n"
1986       << "# Preprocessor definitions for this target.\n"
1987       << "SET(CMAKE_TARGET_DEFINITIONS\n";
1988     for(std::vector<std::string>::const_iterator di = defines.begin();
1989         di != defines.end(); ++di)
1990       {
1991       cmakefileStream
1992         << "  " << this->EscapeForCMake(di->c_str()) << "\n";
1993       }
1994     cmakefileStream
1995       << "  )\n";
1996     }
1997
1998   // Store include transform rule properties.  Write the directory
1999   // rules first because they may be overridden by later target rules.
2000   std::vector<std::string> transformRules;
2001   if(const char* xform =
2002      this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"))
2003     {
2004     cmSystemTools::ExpandListArgument(xform, transformRules);
2005     }
2006   if(const char* xform =
2007      target.GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"))
2008     {
2009     cmSystemTools::ExpandListArgument(xform, transformRules);
2010     }
2011   if(!transformRules.empty())
2012     {
2013     cmakefileStream
2014       << "SET(CMAKE_INCLUDE_TRANSFORMS\n";
2015     for(std::vector<std::string>::const_iterator tri = transformRules.begin();
2016         tri != transformRules.end(); ++tri)
2017       {
2018       cmakefileStream << "  " << this->EscapeForCMake(tri->c_str()) << "\n";
2019       }
2020     cmakefileStream
2021       << "  )\n";
2022     }
2023 }
2024
2025 //----------------------------------------------------------------------------
2026 void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
2027 {
2028   os
2029     << "# CMAKE generated file: DO NOT EDIT!\n"
2030     << "# Generated by \"" << this->GlobalGenerator->GetName() << "\""
2031     << " Generator, CMake Version "
2032     << cmVersion::GetMajorVersion() << "."
2033     << cmVersion::GetMinorVersion() << "\n\n";
2034 }
2035
2036 //----------------------------------------------------------------------------
2037 std::string
2038 cmLocalUnixMakefileGenerator3
2039 ::GetRecursiveMakeCall(const char *makefile, const char* tgt)
2040 {
2041   // Call make on the given file.
2042   std::string cmd;
2043   cmd += "$(MAKE) -f ";
2044   cmd += this->Convert(makefile,NONE,SHELL);
2045   cmd += " ";
2046
2047   // Pass down verbosity level.
2048   if(this->GetMakeSilentFlag().size())
2049     {
2050     cmd += this->GetMakeSilentFlag();
2051     cmd += " ";
2052     }
2053
2054   // Most unix makes will pass the command line flags to make down to
2055   // sub-invoked makes via an environment variable.  However, some
2056   // makes do not support that, so you have to pass the flags
2057   // explicitly.
2058   if(this->GetPassMakeflags())
2059     {
2060     cmd += "-$(MAKEFLAGS) ";
2061     }
2062
2063   // Add the target.
2064   if (tgt && tgt[0] != '\0')
2065     {
2066     // The make target is always relative to the top of the build tree.
2067     std::string tgt2 = this->Convert(tgt, HOME_OUTPUT);
2068
2069     // The target may have been written with windows paths.
2070     cmSystemTools::ConvertToOutputSlashes(tgt2);
2071
2072     // Escape one extra time if the make tool requires it.
2073     if(this->MakeCommandEscapeTargetTwice)
2074       {
2075       tgt2 = this->EscapeForShell(tgt2.c_str(), true, false);
2076       }
2077
2078     // The target name is now a string that should be passed verbatim
2079     // on the command line.
2080     cmd += this->EscapeForShell(tgt2.c_str(), true, false);
2081     }
2082   return cmd;
2083 }
2084
2085 //----------------------------------------------------------------------------
2086 void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
2087 {
2088   os
2089     << "#======================================"
2090     << "=======================================\n";
2091 }
2092
2093 //----------------------------------------------------------------------------
2094 void
2095 cmLocalUnixMakefileGenerator3
2096 ::WriteCMakeArgument(std::ostream& os, const char* s)
2097 {
2098   // Write the given string to the stream with escaping to get it back
2099   // into CMake through the lexical scanner.
2100   os << "\"";
2101   for(const char* c = s; *c; ++c)
2102     {
2103     if(*c == '\\')
2104       {
2105       os << "\\\\";
2106       }
2107     else if(*c == '"')
2108       {
2109       os << "\\\"";
2110       }
2111     else
2112       {
2113       os << *c;
2114       }
2115     }
2116   os << "\"";
2117 }
2118
2119 //----------------------------------------------------------------------------
2120 std::string
2121 cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
2122 {
2123
2124   // Split the path into its components.
2125   std::vector<std::string> components;
2126   cmSystemTools::SplitPath(p, components);
2127
2128   // Return an empty path if there are no components.
2129   if(components.empty())
2130     {
2131     return "\"\"";
2132     }
2133
2134   // Choose a slash direction and fix root component.
2135   const char* slash = "/";
2136 #if defined(_WIN32) && !defined(__CYGWIN__)
2137    if(!cmSystemTools::GetForceUnixPaths())
2138      {
2139      slash = "\\";
2140      for(std::string::iterator i = components[0].begin();
2141        i != components[0].end(); ++i)
2142        {
2143        if(*i == '/')
2144          {
2145          *i = '\\';
2146          }
2147        }
2148      }
2149 #endif
2150
2151   // Begin the quoted result with the root component.
2152   std::string result = "\"";
2153   result += components[0];
2154
2155   // Now add the rest of the components separated by the proper slash
2156   // direction for this platform.
2157   bool first = true;
2158   for(unsigned int i=1; i < components.size(); ++i)
2159     {
2160     // Only the last component can be empty to avoid double slashes.
2161     if(components[i].length() > 0 || (i == (components.size()-1)))
2162       {
2163       if(!first)
2164         {
2165         result += slash;
2166         }
2167       result += components[i];
2168       first = false;
2169       }
2170     }
2171
2172   // Close the quoted result.
2173   result += "\"";
2174
2175   return result;
2176 }
2177
2178 //----------------------------------------------------------------------------
2179 std::string
2180 cmLocalUnixMakefileGenerator3
2181 ::GetTargetDirectory(cmTarget const& target) const
2182 {
2183   std::string dir = cmake::GetCMakeFilesDirectoryPostSlash();
2184   dir += target.GetName();
2185 #if defined(__VMS)
2186   dir += "_dir";
2187 #else
2188   dir += ".dir";
2189 #endif
2190   return dir;
2191 }
2192
2193 //----------------------------------------------------------------------------
2194 cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
2195 cmLocalUnixMakefileGenerator3::GetImplicitDepends(cmTarget const& tgt)
2196 {
2197   return this->ImplicitDepends[tgt.GetName()];
2198 }
2199
2200 //----------------------------------------------------------------------------
2201 void
2202 cmLocalUnixMakefileGenerator3::AddImplicitDepends(cmTarget const& tgt,
2203                                                   const char* lang,
2204                                                   const char* obj,
2205                                                   const char* src)
2206 {
2207   this->ImplicitDepends[tgt.GetName()][lang][obj] = src;
2208 }
2209
2210 //----------------------------------------------------------------------------
2211 void cmLocalUnixMakefileGenerator3
2212 ::CreateCDCommand(std::vector<std::string>& commands, const char *tgtDir,
2213                   cmLocalGenerator::RelativeRoot relRetDir)
2214 {
2215   const char* retDir = this->GetRelativeRootPath(relRetDir);
2216
2217   // do we need to cd?
2218   if (!strcmp(tgtDir,retDir))
2219     {
2220     return;
2221     }
2222
2223   // In a Windows shell we must change drive letter too.  The shell
2224   // used by NMake and Borland make does not support "cd /d" so this
2225   // feature simply cannot work with them (Borland make does not even
2226   // support changing the drive letter with just "d:").
2227   const char* cd_cmd = this->MinGWMake? "cd /d " : "cd ";
2228
2229   if(!this->UnixCD)
2230     {
2231     // On Windows we must perform each step separately and then change
2232     // back because the shell keeps the working directory between
2233     // commands.
2234     std::string cmd = cd_cmd;
2235     cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
2236     commands.insert(commands.begin(),cmd);
2237
2238     // Change back to the starting directory.
2239     cmd = cd_cmd;
2240     cmd += this->ConvertToOutputForExisting(relRetDir, tgtDir);
2241     commands.push_back(cmd);
2242     }
2243   else
2244     {
2245     // On UNIX we must construct a single shell command to change
2246     // directory and build because make resets the directory between
2247     // each command.
2248     std::vector<std::string>::iterator i = commands.begin();
2249     for (; i != commands.end(); ++i)
2250       {
2251       std::string cmd = cd_cmd;
2252       cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
2253       cmd += " && ";
2254       cmd += *i;
2255       *i = cmd;
2256       }
2257     }
2258 }