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