From 141ad7645e4c6d8841f346ecd0fb40383fa3a733 Mon Sep 17 00:00:00 2001
From: Ken Martin <ken.martin@kitware.com>
Date: Wed, 15 Feb 2006 10:34:11 -0500
Subject: ENH: some reorg of the unix makefile generator

---
 Source/CMakeLists.txt                     |    4 +
 Source/cmGlobalUnixMakefileGenerator3.cxx |   34 +-
 Source/cmLocalUnixMakefileGenerator3.cxx  | 2454 ++++++-----------------------
 Source/cmLocalUnixMakefileGenerator3.h    |  230 ++-
 Source/cmMakefileTargetGenerator.h        |    2 +-
 bootstrap                                 |    4 +
 6 files changed, 622 insertions(+), 2106 deletions(-)

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c5d05f1..eebc4f3 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -125,6 +125,10 @@ SET(SRCS
   cmMakeDepend.h
   cmMakefile.cxx
   cmMakefile.h
+  cmMakefileTargetGenerator.cxx
+  cmMakefileExecutableTargetGenerator.cxx
+  cmMakefileLibraryTargetGenerator.cxx
+  cmMakefileUtilityTargetGenerator.cxx
   cmOrderLinkDirectories.cxx
   cmFileTimeComparison.cxx
   cmFileTimeComparison.h
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index d76b6be..d87ccca 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -129,6 +129,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
     
   // Write the do not edit header.
   lg->WriteDisclaimer(makefileStream);
+
   // Write out the "special" stuff
   lg->WriteSpecialTargetsTop(makefileStream);
   // Write the main entry point target.  This must be the VERY first
@@ -390,8 +391,8 @@ cmGlobalUnixMakefileGenerator3
     // write the directory rule
     commands.clear();
     commands.push_back
-      (lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
-                                makeTargetName.c_str()));
+      (lg->GetRecursiveMakeCall
+       ("CMakeFiles/Makefile2",makeTargetName.c_str()));
     
     // Write the rule.
     lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
@@ -520,9 +521,8 @@ cmGlobalUnixMakefileGenerator3
     
     // write the directory rule
     commands.clear();
-    commands.push_back
-      (lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
-                                makeTargetName.c_str()));
+    commands.push_back(lg->GetRecursiveMakeCall
+                       ("CMakeFiles/Makefile2",makeTargetName.c_str()));
     
     // Write the rule.
     lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
@@ -627,8 +627,8 @@ cmGlobalUnixMakefileGenerator3
           
           // Write the rule.
           commands.clear();
-          commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
-                                                      t->second.GetName()));
+          commands.push_back(lg->GetRecursiveMakeCall
+                             ("CMakeFiles/Makefile2",t->second.GetName()));
           depends.clear(); 
           if(sym)
             {
@@ -691,22 +691,22 @@ cmGlobalUnixMakefileGenerator3
         {
         makeTargetName = localName;
         makeTargetName += "/depend";
-        commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
-                                                    makeTargetName.c_str()));
+        commands.push_back(lg->GetRecursiveMakeCall
+                           (makefileName.c_str(),makeTargetName.c_str()));
         
         // add requires if we need it for this generator
         if (needRequiresStep)
           {
           makeTargetName = localName;
           makeTargetName += "/requires";
-          commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
-                                                      makeTargetName.c_str()));
+          commands.push_back(lg->GetRecursiveMakeCall
+                             (makefileName.c_str(),makeTargetName.c_str()));
           }
         }
       makeTargetName = localName;
       makeTargetName += "/build";
-      commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
-                                                  makeTargetName.c_str()));
+      commands.push_back(lg->GetRecursiveMakeCall
+                         (makefileName.c_str(),makeTargetName.c_str()));
 
       // Write the rule.
       localName += "/all";
@@ -732,8 +732,8 @@ cmGlobalUnixMakefileGenerator3
 
       // Write the rule.
       commands.clear();
-      commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
-                                                  localName.c_str()));
+      commands.push_back(lg->GetRecursiveMakeCall
+                         ("CMakeFiles/Makefile2",localName.c_str()));
       depends.clear();
       if(sym)
         {
@@ -763,8 +763,8 @@ cmGlobalUnixMakefileGenerator3
         depends.push_back(sym);
         }
       commands.clear();
-      commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
-                                                  makeTargetName.c_str()));
+      commands.push_back(lg->GetRecursiveMakeCall
+                         (makefileName.c_str(), makeTargetName.c_str()));
       lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
                         makeTargetName.c_str(), depends, commands);
       commands.clear();
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index ebf8060..4c26db3 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -20,6 +20,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
+#include "cmMakefileTargetGenerator.h"
 #include "cmSourceFile.h"
 #include "cmake.h"
 
@@ -34,10 +35,6 @@
 #include <memory> // auto_ptr
 #include <queue>
 
-// TODO: Add "help" target.
-// TODO: Identify remaining relative path violations.
-// TODO: Need test for separate executable/library output path.
-
 //----------------------------------------------------------------------------
 cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
 {
@@ -82,18 +79,13 @@ void cmLocalUnixMakefileGenerator3::Generate()
   std::string empty;
   for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
     {
-    if((t->second.GetType() == cmTarget::EXECUTABLE) ||
-       (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
-       (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
-       (t->second.GetType() == cmTarget::MODULE_LIBRARY))
+    cmMakefileTargetGenerator *tg = 
+      cmMakefileTargetGenerator::New(this, t->first, &(t->second));
+    if (tg)
       {
+      this->TargetGenerators.push_back(tg);
       t->second.TraceVSDependencies(empty, m_Makefile);
-      this->WriteTargetRuleFiles(t->second);
-      }
-    else if(t->second.GetType() == cmTarget::UTILITY)
-      {
-      t->second.TraceVSDependencies(empty, m_Makefile);
-      this->WriteUtilityRuleFiles(t->second);
+      tg->WriteRuleFiles();
       }
     }
 
@@ -102,6 +94,15 @@ void cmLocalUnixMakefileGenerator3::Generate()
   
   // Write the cmake file with information for this directory.
   this->WriteDirectoryInformationFile();
+  
+  // delete the makefile target generator objects
+  for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = 
+         this->TargetGenerators.begin();
+       mtgIter != this->TargetGenerators.end(); ++mtgIter)
+    {
+    delete *mtgIter;
+    }  
+  this->TargetGenerators.clear();
 }
 
 
@@ -164,27 +165,129 @@ void cmLocalUnixMakefileGenerator3::FormatOutputPath(std::string& path,
     }
 }
 
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
+{
+  // generate the includes
+  std::string ruleFileName = "Makefile";
+
+  // Open the rule file.  This should be copy-if-different because the
+  // rules may depend on this file itself.
+  std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
+  cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+  if(!ruleFileStream)
+    {
+    return;
+    }
+  // always write the top makefile
+  if (m_Parent)
+    {
+    ruleFileStream.SetCopyIfDifferent(true);
+    }
+  
+  // write the all rules
+  this->WriteLocalAllRules(ruleFileStream);
+  
+  // only write local targets unless at the top Keep track of targets already
+  // listed.
+  std::set<cmStdString> emittedTargets;
+  if (m_Parent)
+    {
+    // write our targets, and while doing it collect up the object
+    // file rules
+    this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets);
+    }
+  else
+    {
+    cmGlobalUnixMakefileGenerator3 *gg = 
+      static_cast<cmGlobalUnixMakefileGenerator3*>(m_GlobalGenerator);
+    gg->WriteConvenienceRules(ruleFileStream,emittedTargets);
+    }
+  
+  std::vector<std::string> depends;
+  std::vector<std::string> commands;
+
+  // now write out the object rules
+  // for each object file name
+  for (std::map<cmStdString,std::vector<cmTarget *> >::iterator lo = 
+         m_LocalObjectFiles.begin();
+       lo != m_LocalObjectFiles.end(); ++lo)
+    {
+    commands.clear();
+    // for each target using the object file
+    for (std::vector<cmTarget *>::iterator to = 
+           lo->second.begin(); to != lo->second.end(); ++to)
+      {
+      std::string tgtMakefileName = this->GetRelativeTargetDirectory(**to);
+      std::string targetName = tgtMakefileName;
+      tgtMakefileName += "/build.make";
+      targetName += "/";
+      targetName += lo->first.c_str();
+      commands.push_back(this->GetRecursiveMakeCall
+                         (tgtMakefileName.c_str(),targetName.c_str()));  
+      this->CreateCDCommand(commands,
+                                    m_Makefile->GetHomeOutputDirectory(),
+                                    m_Makefile->GetStartOutputDirectory());
+      }
+    this->WriteMakeRule(ruleFileStream, 
+                        "target for object file", 
+                        lo->first.c_str(), depends, commands);
+    }
+
+  // add a help target as long as there isn;t a real target named help
+  if(emittedTargets.insert("help").second)
+    {
+    cmGlobalUnixMakefileGenerator3 *gg = 
+      static_cast<cmGlobalUnixMakefileGenerator3*>(m_GlobalGenerator);
+    gg->WriteHelpRule(ruleFileStream,this);
+    }
+
+  this->WriteSpecialTargetsBottom(ruleFileStream);
+}
 
 void cmLocalUnixMakefileGenerator3
-::WriteCustomCommands(std::ostream& ruleFileStream,
-                      std::vector<std::string>& cleanFiles)
+::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
+                            std::set<cmStdString> &emitted)
 {
-  // add custom commands to the clean rules?
-  const char* clean_no_custom = m_Makefile->GetProperty("CLEAN_NO_CUSTOM");
-  bool clean = cmSystemTools::IsOff(clean_no_custom);
-  
-  // Generate the rule files for each custom command.
-  const std::vector<cmSourceFile*> &classes = m_Makefile->GetSourceFiles();
-  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); 
-      i != classes.end(); i++)
+  std::vector<std::string> depends;
+  std::vector<std::string> commands;
+
+  // for each target we just provide a rule to cd up to the top and do a make
+  // on the target
+  cmTargets& targets = m_Makefile->GetTargets();
+  std::string localName;
+  for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
     {
-    if(cmCustomCommand* cc = (*i)->GetCustomCommand())
+    if((t->second.GetType() == cmTarget::EXECUTABLE) ||
+       (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
+       (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
+       (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+       (t->second.GetType() == cmTarget::UTILITY))
       {
-      this->GenerateCustomRuleFile(*cc,ruleFileStream);
-      if (clean)
+      emitted.insert(t->second.GetName());
+
+      // for subdirs add a rule to build this specific target by name.
+      localName = this->GetRelativeTargetDirectory(t->second);
+      localName += "/rule";
+      commands.clear();
+      depends.clear();
+      
+      // Build the target for this pass.
+      commands.push_back(this->GetRecursiveMakeCall
+                         ("CMakeFiles/Makefile2",localName.c_str()));
+      this->CreateCDCommand(commands,
+                            m_Makefile->GetHomeOutputDirectory(),
+                            m_Makefile->GetStartOutputDirectory());
+      this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
+                          localName.c_str(), depends, commands);
+      
+      // Add a target with the canonical name (no prefix, suffix or path).
+      if(localName != t->second.GetName())
         {
-        cleanFiles.push_back
-          (this->Convert(cc->GetOutput(),START_OUTPUT,SHELL));
+        commands.clear();
+        depends.push_back(localName);
+        this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
+                          t->second.GetName(), depends, commands);
         }
       }
     }
@@ -293,692 +396,91 @@ cmLocalUnixMakefileGenerator3
 }
 
 
-//----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
-{
-  os
-    << "# CMAKE generated file: DO NOT EDIT!\n"
-    << "# Generated by \"" << m_GlobalGenerator->GetName() << "\""
-    << " Generator, CMake Version "
-    << cmMakefile::GetMajorVersion() << "."
-    << cmMakefile::GetMinorVersion() << "\n\n";
-}
-
 const std::string &cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
 {
   return m_HomeRelativeOutputPath;
 }
 
+
 //----------------------------------------------------------------------------
 void
 cmLocalUnixMakefileGenerator3
-::WriteTargetRuleFiles(cmTarget& target)
+::WriteMakeRule(std::ostream& os,
+                const char* comment,
+                const char* target,
+                const std::vector<std::string>& depends,
+                const std::vector<std::string>& commands)
 {
-  // Create a directory for this target.
-  std::string dir = m_Makefile->GetStartOutputDirectory();
-  dir += "/";
-  dir += this->GetTargetDirectory(target);
-  cmSystemTools::MakeDirectory(dir.c_str());
-
-  // Generate the build-time dependencies file for this target.
-  std::string depBase = dir;
-  depBase += "/";
-  depBase += target.GetName();
-
-  // Construct the rule file name.
-  std::string ruleFileName = dir;
-  ruleFileName += "/build.make";
-
-  // Open the rule file.  This should be copy-if-different because the
-  // rules may depend on this file itself.
-  std::string ruleFileNameFull = ruleFileName;
-  cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
-  ruleFileStream.SetCopyIfDifferent(true);
-  if(!ruleFileStream)
+  // Make sure there is a target.
+  if(!target || !*target)
     {
+    cmSystemTools::Error("No target for WriteMakeRule! called with comment: ",
+                         comment);
     return;
     }
-  this->WriteDisclaimer(ruleFileStream);
-  this->WriteSpecialTargetsTop(ruleFileStream);
-  this->WriteMakeVariables(ruleFileStream);
-  
-  // Open the flags file.  This should be copy-if-different because the
-  // rules may depend on this file itself.
-  std::string flagFileName = dir;
-  flagFileName += "/flags.make";
-  std::string flagFileNameFull = flagFileName;
-  cmGeneratedFileStream flagFileStream(flagFileNameFull.c_str());
-  flagFileStream.SetCopyIfDifferent(true);
-  if(!flagFileStream)
+
+  std::string replace;
+
+  // Write the comment describing the rule in the makefile.
+  if(comment)
     {
-    return;
-    }
-  this->WriteDisclaimer(flagFileStream);
-
-  // Include the dependencies for the target.
-  std::string depPath = dir;
-  depPath += "/depend.make";
-  depPath = this->Convert(depPath.c_str(),HOME_OUTPUT,MAKEFILE);
-  ruleFileStream
-    << "# Include any dependencies generated for this target.\n"
-    << m_IncludeDirective << " "
-    << depPath
-    << "\n\n";
-  
-  // Include the flags for the target.
-  flagFileName = this->Convert(flagFileName.c_str(), HOME_OUTPUT, MAKEFILE);
-  ruleFileStream
-    << "# Include the compile flags for this target's objects.\n"
-    << m_IncludeDirective << " "
-    << flagFileName
-    << "\n\n";
-  
-  // make sure the depend file exists
-  depPath = dir;
-  depPath += "/depend.make";
-  depPath = this->Convert(depPath.c_str(),FULL,UNCHANGED);
-  if (!cmSystemTools::FileExists(depPath.c_str()))
-    {
-    // Write an empty dependency file.
-    cmGeneratedFileStream depFileStream(depPath.c_str());
-    depFileStream
-      << "# Empty dependencies file for " << target.GetName() << ".\n"
-      << "# This may be replaced when dependencies are built." << std::endl;
-    }
-  
-  // First generate the object rule files.  Save a list of all object
-  // files for this target.
-  std::vector<std::string> objects;
-  std::vector<std::string> external_objects;
-  const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
-  for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
-      source != sources.end(); ++source)
-    {
-    if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
-       !(*source)->GetCustomCommand())
+    replace = comment;
+    std::string::size_type lpos = 0;
+    std::string::size_type rpos;
+    while((rpos = replace.find('\n', lpos)) != std::string::npos)
       {
-      if(!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str()))
-        {
-        // Generate this object file's rule file.
-        this->WriteObjectRuleFiles(target, *(*source), objects, 
-                                   ruleFileStream, flagFileStream);
-        }
-      else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
-        {
-        // This is an external object file.  Just add it.
-        external_objects.push_back((*source)->GetFullPath());
-        }
-      else
-        {
-        // We only get here if a source file is not an external object
-        // and has an extension that is listed as an ignored file type
-        // for this language.  No message or diagnosis should be
-        // given.
-        }
+      os << "# " << replace.substr(lpos, rpos-lpos) << "\n";
+      lpos = rpos+1;
       }
+    os << "# " << replace.substr(lpos) << "\n";
     }
-  
-  // write language flags for target
-  std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& 
-    checkSet = this->GetIntegrityCheckSet()[target.GetName()];
-  for(std::map<cmStdString, 
-        cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
-        l = checkSet.begin(); l != checkSet.end(); ++l)
+
+  // Construct the left hand side of the rule.
+  replace = target;
+  std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
+  tgt = this->ConvertToMakeTarget(tgt.c_str());
+  const char* space = "";
+  if(tgt.size() == 1)
     {
-    const char *lang = l->first.c_str();
-    std::string flags;
-    // Add the export symbol definition for shared library objects.
-    bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
-                   (target.GetType() == cmTarget::MODULE_LIBRARY));
-    if(shared)
-      {
-      flags += "-D";
-      if(const char* custom_export_name = target.GetProperty("DEFINE_SYMBOL"))
-        {
-        flags += custom_export_name;
-        }
-      else
-        {
-        std::string in = target.GetName();
-        in += "_EXPORTS";
-        flags += cmSystemTools::MakeCindentifier(in.c_str());
-        }
-      }
-    
-    // Add language-specific flags.
-    this->AddLanguageFlags(flags, lang);
-    
-    // Add shared-library flags if needed.
-    this->AddSharedFlags(flags, lang, shared);
-    
-    // Add include directory flags.
-    this->AppendFlags(flags, this->GetIncludeFlags(lang));
-    // Add include directory flags.
-    this->AppendFlags(flags, this->GetFrameworkFlags(target).c_str());
+    // Add a space before the ":" to avoid drive letter confusion on
+    // Windows.
+    space = " ";
+    }
 
-    flagFileStream << lang << "_FLAGS = " << flags
-                   << "\n"
-                   << "\n";
+  // Write the rule.
+  if(depends.empty())
+    {
+    // No dependencies.  The commands will always run.
+    os << tgt.c_str() << space << ":\n";
     }
-  
-  // write the custom commands for this target
-  std::vector<std::string> cleanFiles;
-  // Look for files registered for cleaning in this directory.
-  if(const char* additional_clean_files =
-     m_Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES"))
+  else
     {
-    cmSystemTools::ExpandListArgument(additional_clean_files, cleanFiles);
-    }  
-  this->WriteCustomCommands(ruleFileStream,cleanFiles);
-
-  // Include the rule file for each object.
-  std::string relPath = this->GetHomeRelativeOutputPath();
-  std::string objTarget;
-
-  // Write the rule for this target type.
-  switch(target.GetType())
-    {
-    case cmTarget::STATIC_LIBRARY:
-      this->WriteStaticLibraryRule(ruleFileStream, ruleFileName.c_str(),
-                                   target, objects, external_objects,
-                                   cleanFiles);
-      break;
-    case cmTarget::SHARED_LIBRARY:
-      this->WriteSharedLibraryRule(ruleFileStream, ruleFileName.c_str(),
-                                   target, objects, external_objects, 
-                                   cleanFiles);
-      break;
-    case cmTarget::MODULE_LIBRARY:
-      this->WriteModuleLibraryRule(ruleFileStream, ruleFileName.c_str(),
-                                   target, objects, external_objects, 
-                                   cleanFiles);
-      break;
-    case cmTarget::EXECUTABLE:
-      this->WriteExecutableRule(ruleFileStream, ruleFileName.c_str(),
-                                target, objects, external_objects,
-                                cleanFiles);
-      break;
-    default:
-      break;
-    }
-
-  // Write the requires target.
-  this->WriteTargetRequiresRule(ruleFileStream, target, objects);
-
-  // Write clean target
-  this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles);
-}
-
-//----------------------------------------------------------------------------
-std::string 
-cmLocalUnixMakefileGenerator3
-::GetFrameworkFlags(cmTarget& 
-#ifdef __APPLE__                    
-                    target
-#endif
-  )
-{
-#ifndef __APPLE__
-  return std::string();
-#else
-  std::set<cmStdString> emitted;
-  std::vector<std::string> includes;
-  this->GetIncludeDirectories(includes);
-  std::vector<std::string>::iterator i;
-  // check all include directories for frameworks as this
-  // will already have added a -F for the framework
-  for(i = includes.begin(); i != includes.end(); ++i)
-    {
-    if(cmSystemTools::IsPathToFramework(i->c_str()))
+    // Split dependencies into multiple rule lines.  This allows for
+    // very long dependency lists even on older make implementations.
+    for(std::vector<std::string>::const_iterator dep = depends.begin();
+        dep != depends.end(); ++dep)
       {
-      std::string frameworkDir = *i;
-      frameworkDir += "/../";
-      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
-      emitted.insert(frameworkDir);
+      replace = *dep;
+      replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
+      replace = this->ConvertToMakeTarget(replace.c_str());
+      os << tgt.c_str() << space << ": " << replace.c_str() << "\n";
       }
     }
 
-  std::string flags;
-  std::vector<std::string>& frameworks = target.GetFrameworks();
-  for(i = frameworks.begin();
-      i != frameworks.end(); ++i)
+  // Write the list of commands.
+  for(std::vector<std::string>::const_iterator i = commands.begin();
+      i != commands.end(); ++i)
     {
-    if(emitted.insert(*i).second)
-      {
-      flags += "-F";
-      flags += this->ConvertToOutputForExisting(i->c_str());
-      flags += " ";
-      }
+    replace = *i;
+    os << "\t" << replace.c_str() << "\n";
     }
-  return flags;
-#endif
+  os << "\n";
 }
 
 //----------------------------------------------------------------------------
 void
 cmLocalUnixMakefileGenerator3
-::WriteObjectDependRules(cmSourceFile& source,
-                         std::vector<std::string>& depends)
-{
-  // Create the list of dependencies known at cmake time.  These are
-  // shared between the object file and dependency scanning rule.
-  depends.push_back(source.GetFullPath());
-  if(const char* objectDeps = source.GetProperty("OBJECT_DEPENDS"))
-    {
-    std::vector<std::string> deps;
-    cmSystemTools::ExpandListArgument(objectDeps, deps);
-    for(std::vector<std::string>::iterator i = deps.begin();
-        i != deps.end(); ++i)
-      {
-      depends.push_back(i->c_str());
-      }
-    }
-}
-
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteObjectBuildFile(std::string &obj,
-                       const char *lang, 
-                       cmTarget& target, 
-                       cmSourceFile& source,
-                       std::vector<std::string>& depends,
-                       std::ostream &ruleFileStream,
-                       std::ostream &flagFileStream)
-{
-  // Open the rule file for writing.  This should be copy-if-different
-  // because the rules may depend on this file itself.
-  std::string ruleFileName = m_Makefile->GetStartOutputDirectory();
-  ruleFileName += "/";
-  ruleFileName += this->GetTargetDirectory(target);
-  ruleFileName += "/build.make";
-  std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
-
-  std::string flagFileName = this->GetTargetDirectory(target);
-  flagFileName += "/flags.make";
-  std::string flagFileNameFull = this->ConvertToFullPath(flagFileName);
-  this->AppendRuleDepend(depends, flagFileNameFull.c_str());
-
-  // generate the depend scanning rule
-  this->WriteObjectDependRules(source, depends);
-
-  std::string relativeObj = this->GetHomeRelativeOutputPath();
-  relativeObj += obj;
-  if(m_Makefile->GetDefinition("CMAKE_WINDOWS_OBJECT_PATH"))
-    {
-    relativeObj = cmSystemTools::ConvertToOutputPath(relativeObj.c_str());
-    }
-  // Write the build rule.
-  // Build the set of compiler flags.
-  std::string flags;
-  if(target.GetProperty("COMPILE_FLAGS"))
-    {
-    this->AppendFlags(flags, target.GetProperty("COMPILE_FLAGS"));
-    }
-
-  // Add flags from source file properties.
-  if (source.GetProperty("COMPILE_FLAGS"))
-    {
-    this->AppendFlags(flags, source.GetProperty("COMPILE_FLAGS"));
-    flagFileStream << "# Custom flags: "
-                   << relativeObj << "_FLAGS = "
-                   << source.GetProperty("COMPILE_FLAGS")
-                   << "\n"
-                   << "\n";
-    }
-  
-  // Add language-specific flags.
-  std::string langFlags = "$(";
-  langFlags += lang;
-  langFlags += "_FLAGS)";
-  this->AppendFlags(flags, langFlags.c_str());
-  
-  // Get the output paths for source and object files.
-  std::string sourceFile = source.GetFullPath();
-  if(m_UseRelativePaths)
-    {
-    sourceFile = this->Convert(sourceFile.c_str(),HOME_OUTPUT);
-    }
-  sourceFile = this->Convert(sourceFile.c_str(),NONE,SHELL);
-  std::string objectFile = this->Convert(obj.c_str(),START_OUTPUT,SHELL);
-
-  // Construct the build message.
-  std::vector<std::string> no_commands;
-  std::vector<std::string> commands;
-  std::string buildEcho = "Building ";
-  buildEcho += lang;
-  buildEcho += " object ";
-  buildEcho += relativeObj;
-  this->AppendEcho(commands, buildEcho.c_str());
-
-  // Construct the compile rules.
-  std::string compileRuleVar = "CMAKE_";
-  compileRuleVar += lang;
-  compileRuleVar += "_COMPILE_OBJECT";
-  std::string compileRule =
-    m_Makefile->GetRequiredDefinition(compileRuleVar.c_str());
-  cmSystemTools::ExpandListArgument(compileRule, commands);
-
-  // Expand placeholders in the commands.
-  for(std::vector<std::string>::iterator i = commands.begin();
-      i != commands.end(); ++i)
-    {
-    this->ExpandRuleVariables(*i,
-                              lang,
-                              0, // no objects
-                              0, // no target
-                              0, // no link libs
-                              sourceFile.c_str(),
-                              relativeObj.c_str(),
-                              flags.c_str());
-    }
-
-  // Make the target dependency scanning rule include cmake-time-known
-  // dependencies.  The others are handled by the check-build-system
-  // path.
-  std::string depMark = this->GetRelativeTargetDirectory(target);
-  depMark += "/depend.make.mark";
-  this->WriteMakeRule(ruleFileStream, 0,
-                      depMark.c_str(), depends, no_commands);
-
-  // Write the rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      relativeObj.c_str(), depends, commands);
-
-  // If the language needs provides-requires mode, create the
-  // corresponding targets.
-  std::string objectRequires = relativeObj;
-  objectRequires += ".requires";
-  std::vector<std::string> p_depends;
-  // always provide an empty requires target
-  this->WriteMakeRule(ruleFileStream, 0,
-                      objectRequires.c_str(), p_depends, no_commands);
-
-  // write a build rule to recursively build what this obj provides
-  std::string objectProvides = relativeObj;
-  objectProvides += ".provides";
-  std::string temp = relativeObj;
-  temp += ".provides.build";
-  std::vector<std::string> r_commands;
-  std::string tgtMakefileName = this->GetRelativeTargetDirectory(target);
-  tgtMakefileName += "/build.make";
-  r_commands.push_back(this->GetRecursiveMakeCall(tgtMakefileName.c_str(),
-                                                  temp.c_str()));
-  p_depends.clear();
-  p_depends.push_back(objectRequires);
-  this->WriteMakeRule(ruleFileStream, 0,
-                      objectProvides.c_str(), p_depends, r_commands);
-  
-  // write the provides.build rule dependency on the obj file
-  p_depends.clear();
-  p_depends.push_back(relativeObj);
-  this->WriteMakeRule(ruleFileStream, 0,
-                      temp.c_str(), p_depends, no_commands);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteObjectRuleFiles(cmTarget& target, cmSourceFile& source,
-                       std::vector<std::string>& objects, 
-                       std::ostream &ruleFileStream,
-                       std::ostream &flagFileStream)
-{
-  // Identify the language of the source file.
-  const char* lang = this->GetSourceFileLanguage(source);
-  if(!lang)
-    {
-    // If language is not known, this is an error.
-    cmSystemTools::Error("Source file \"", source.GetFullPath().c_str(),
-                         "\" has unknown type.");
-    return;
-    }
-
-  // Get the full path name of the object file.
-  std::string objNoTargetDir;
-  std::string obj = this->GetObjectFileName(target, source, &objNoTargetDir);
-  // Avoid generating duplicate rules.
-  if(m_ObjectFiles.find(obj) == m_ObjectFiles.end())
-    {
-    m_ObjectFiles.insert(obj);
-    }
-  else
-    {
-    cmOStringStream err;
-    err << "Warning: Source file \""
-        << source.GetSourceName().c_str() << "."
-        << source.GetSourceExtension().c_str()
-        << "\" is listed multiple times for target \"" << target.GetName()
-        << "\".";
-    cmSystemTools::Message(err.str().c_str(), "Warning");
-    return;
-    }
-  
-  // Create the directory containing the object file.  This may be a
-  // subdirectory under the target's directory.
-  std::string dir = cmSystemTools::GetFilenamePath(obj.c_str());
-  cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
-
-  // Save this in the target's list of object files.
-  objects.push_back(obj);
-  std::string relativeObj = this->GetHomeRelativeOutputPath();
-  relativeObj += obj;
-  // we compute some depends when writing the depend.make that we will also
-  // use in the build.make, same with depMakeFile
-  std::vector<std::string> depends;
-  std::string depMakeFile;
-  
-  // generate the build rule file
-  this->WriteObjectBuildFile(obj, lang, target, source, depends,
-                             ruleFileStream, flagFileStream);
-  
-  // The object file should be checked for dependency integrity.
-  m_CheckDependFiles[target.GetName()][lang].insert(&source);
-  // add this to the list of objects for this local generator
-  if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str()))
-    {
-    objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir);
-    }
-  m_LocalObjectFiles[objNoTargetDir].push_back(&target);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::GenerateCustomRuleFile(const cmCustomCommand& cc,
-                         std::ostream &ruleFileStream)
-{
-  // Convert the output name to a relative path if possible.
-  std::string output = this->Convert(cc.GetOutput(),START_OUTPUT);
-
-  // Collect the commands.
-  std::vector<std::string> commands;
-  std::string preEcho = "Generating ";
-  preEcho += output;
-  this->AppendEcho(commands, preEcho.c_str());
-  this->AppendCustomCommand(commands, cc);
-  
-  // Collect the dependencies.
-  std::vector<std::string> depends;
-  this->AppendCustomDepend(depends, cc);
-
-  // Write the rule.
-  const char* comment = 0;
-  if(cc.GetComment() && *cc.GetComment())
-    {
-    comment = cc.GetComment();
-    }
-  this->WriteMakeRule(ruleFileStream, comment,
-                      cc.GetOutput(), depends, commands);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteUtilityRuleFiles(cmTarget& target)
-{
-  // Create a directory for this target.
-  std::string dir = this->GetTargetDirectory(target);
-  cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
-
-  // Construct the name of the rule file.
-  std::string ruleFileName = dir;
-  ruleFileName += "/build.make";
-
-  // Open the rule file.  This should be copy-if-different because the
-  // rules may depend on this file itself.
-  std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
-  cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
-  ruleFileStream.SetCopyIfDifferent(true);
-  if(!ruleFileStream)
-    {
-    return;
-    }
-  this->WriteDisclaimer(ruleFileStream);
-  this->WriteMakeVariables(ruleFileStream);
-  ruleFileStream
-    << "# Utility rule file for " << target.GetName() << ".\n\n";
-
-  // write the custom commands for this target
-  std::vector<std::string> cleanFiles;
-  if(const char* additional_clean_files =
-     m_Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES"))
-    {
-    cmSystemTools::ExpandListArgument(additional_clean_files, cleanFiles);
-    }  
-  this->WriteCustomCommands(ruleFileStream, cleanFiles);
-
-  // Collect the commands and dependencies.
-  std::vector<std::string> commands;
-  std::vector<std::string> depends;
-  const char* sym = m_Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE");
-  if(sym)
-    {
-    depends.push_back(sym);
-    }
-
-  // Utility targets store their rules in pre- and post-build commands.
-  this->AppendCustomDepends(depends, target.GetPreBuildCommands());
-  this->AppendCustomDepends(depends, target.GetPostBuildCommands());
-  this->AppendCustomCommands(commands, target.GetPreBuildCommands());
-  this->AppendCustomCommands(commands, target.GetPostBuildCommands());
-
-  // Add dependencies on targets that must be built first.
-  this->AppendTargetDepends(depends, target);
-
-  // Add a dependency on the rule file itself.
-  std::string relPath = this->GetHomeRelativeOutputPath();
-  std::string objTarget = relPath;
-  objTarget += ruleFileName;
-  this->AppendRuleDepend(depends, objTarget.c_str());
-
-  // Write the rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      target.GetName(), depends, commands);
-
-  // Write convenience targets.
-  dir = m_Makefile->GetStartOutputDirectory();
-  dir += "/";
-  dir += this->GetTargetDirectory(target);
-  std::string buildTargetRuleName = dir;
-  buildTargetRuleName += "/build";
-  buildTargetRuleName = 
-    this->Convert(buildTargetRuleName.c_str(),HOME_OUTPUT,MAKEFILE);
-  this->WriteConvenienceRule(ruleFileStream, target.GetName(),
-                             buildTargetRuleName.c_str());
-
-  // Write clean target
-  this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteMakeRule(std::ostream& os,
-                const char* comment,
-                const char* target,
-                const std::vector<std::string>& depends,
-                const std::vector<std::string>& commands)
-{
-  // Make sure there is a target.
-  if(!target || !*target)
-    {
-    cmSystemTools::Error("No target for WriteMakeRule! called with comment: ",
-                         comment);
-    return;
-    }
-
-  std::string replace;
-
-  // Write the comment describing the rule in the makefile.
-  if(comment)
-    {
-    replace = comment;
-    std::string::size_type lpos = 0;
-    std::string::size_type rpos;
-    while((rpos = replace.find('\n', lpos)) != std::string::npos)
-      {
-      os << "# " << replace.substr(lpos, rpos-lpos) << "\n";
-      lpos = rpos+1;
-      }
-    os << "# " << replace.substr(lpos) << "\n";
-    }
-
-  // Construct the left hand side of the rule.
-  replace = target;
-  std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
-  tgt = this->ConvertToMakeTarget(tgt.c_str());
-  const char* space = "";
-  if(tgt.size() == 1)
-    {
-    // Add a space before the ":" to avoid drive letter confusion on
-    // Windows.
-    space = " ";
-    }
-
-  // Write the rule.
-  if(depends.empty())
-    {
-    // No dependencies.  The commands will always run.
-    os << tgt.c_str() << space << ":\n";
-    }
-  else
-    {
-    // Split dependencies into multiple rule lines.  This allows for
-    // very long dependency lists even on older make implementations.
-    for(std::vector<std::string>::const_iterator dep = depends.begin();
-        dep != depends.end(); ++dep)
-      {
-      replace = *dep;
-      replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
-      replace = this->ConvertToMakeTarget(replace.c_str());
-      os << tgt.c_str() << space << ": " << replace.c_str() << "\n";
-      }
-    }
-
-  // Write the list of commands.
-  for(std::vector<std::string>::const_iterator i = commands.begin();
-      i != commands.end(); ++i)
-    {
-    replace = *i;
-    os << "\t" << replace.c_str() << "\n";
-    }
-  os << "\n";
-}
-
-//----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
-{
-  os
-    << "#======================================"
-    << "=======================================\n";
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteMakeVariables(std::ostream& makefileStream)
+::WriteMakeVariables(std::ostream& makefileStream)
 {
   this->WriteDivider(makefileStream);
   makefileStream
@@ -1308,1060 +810,74 @@ cmLocalUnixMakefileGenerator3
     }
 }
 
+
 //----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteTargetRequiresRule(std::ostream& ruleFileStream, cmTarget& target,
-                          const std::vector<std::string>& objects)
+std::string
+cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(cmTarget& target)
 {
-  std::vector<std::string> depends;
-  std::vector<std::string> no_commands;
+  std::string dir = m_Makefile->GetStartOutputDirectory();
+  dir += "/";
+  dir += this->GetTargetDirectory(target);
+  dir = cmSystemTools::RelativePath(m_Makefile->GetHomeOutputDirectory(), dir.c_str());
+  return this->Convert(dir.c_str(),NONE,MAKEFILE);
+}
+
 
-  // Construct the name of the dependency generation target.
-  std::string depTarget = this->GetRelativeTargetDirectory(target);
-  depTarget += "/requires";
 
-  // This target drives dependency generation for all object files.
-  std::string relPath = this->GetHomeRelativeOutputPath();
-  std::string objTarget;
-  for(std::vector<std::string>::const_iterator obj = objects.begin();
-      obj != objects.end(); ++obj)
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendRuleDepend(std::vector<std::string>& depends,
+                   const char* ruleFileName)
+{
+  // Add a dependency on the rule file itself unless an option to skip
+  // it is specifically enabled by the user or project.
+  const char* nodep = m_Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
+  if(!nodep || cmSystemTools::IsOff(nodep))
     {
-    objTarget = relPath;
-    objTarget += *obj;
-    objTarget += ".requires";
-    depends.push_back(objTarget);
+    depends.push_back(ruleFileName);
     }
-
-  // Write the rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      depTarget.c_str(), depends, no_commands);
 }
 
 //----------------------------------------------------------------------------
 void
 cmLocalUnixMakefileGenerator3
-::WriteExecutableRule(std::ostream& ruleFileStream,
-                      const char* ruleFileName,
-                      cmTarget& target,
-                      const std::vector<std::string>& objects,
-                      const std::vector<std::string>& external_objects,
-                      std::vector<std::string>& cleanFiles)
+::AppendCustomDepends(std::vector<std::string>& depends,
+                      const std::vector<cmCustomCommand>& ccs)
 {
-  // Write the dependency generation rule.
-  this->WriteTargetDependRule(ruleFileStream, target);
-
-  std::vector<std::string> commands;
-
-  std::string relPath = this->GetHomeRelativeOutputPath();
-  std::string objTarget;
-
-  // Build list of dependencies.
-  std::vector<std::string> depends;
-  for(std::vector<std::string>::const_iterator obj = objects.begin();
-      obj != objects.end(); ++obj)
+  for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
+      i != ccs.end(); ++i)
     {
-    objTarget = relPath;
-    objTarget += *obj;
-    depends.push_back(objTarget);
+    this->AppendCustomDepend(depends, *i);
     }
+}
 
-  // Add dependencies on targets that must be built first.
-  this->AppendTargetDepends(depends, target);
-
-  // Add a dependency on the rule file itself.
-  this->AppendRuleDepend(depends, ruleFileName);
-
-  for(std::vector<std::string>::const_iterator obj = external_objects.begin();
-      obj != external_objects.end(); ++obj)
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCustomDepend(std::vector<std::string>& depends,
+                     const cmCustomCommand& cc)
+{
+  for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
+      d != cc.GetDepends().end(); ++d)
     {
-    depends.push_back(*obj);
+    // Lookup the real name of the dependency in case it is a CMake target.
+    std::string dep = this->GetRealDependency(d->c_str(),
+                                              m_ConfigurationName.c_str());
+    depends.push_back(dep);
     }
+}
 
-  // from here up is the same for exe or lib
-
-  // Get the name of the executable to generate.
-  std::string targetName;
-  std::string targetNameReal;
-  target.GetExecutableNames(targetName, targetNameReal,
-                            m_ConfigurationName.c_str());
-
-  // Construct the full path version of the names.
-  std::string outpath = m_ExecutableOutputPath;
-  if(outpath.length() == 0)
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCustomCommands(std::vector<std::string>& commands,
+                       const std::vector<cmCustomCommand>& ccs)
+{
+  for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
+      i != ccs.end(); ++i)
     {
-    outpath = m_Makefile->GetStartOutputDirectory();
-    outpath += "/";
-    }
-#ifdef __APPLE__
-  if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
-    {
-    // Make bundle directories
-    outpath += target.GetName();
-    outpath += ".app/Contents/MacOS/";
-    std::string f1 = m_Makefile->GetModulesFile("MacOSXBundleInfo.plist.in");
-    if ( f1.size() == 0 )
-      {
-      cmSystemTools::Error("could not find Mac OSX bundle template file.");
-      }
-    std::string macdir = m_Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
-    if ( macdir.size() == 0 )
-      {
-      macdir = m_Makefile->GetCurrentOutputDirectory();
-      }
-    if(macdir.size() && macdir[macdir.size()-1] != '/')
-      {
-      macdir += "/";
-      }
-    macdir += target.GetName();
-    macdir += ".app/Contents/";
-    std::string f2 = macdir + "Info.plist";
-    macdir += "MacOS";
-    cmSystemTools::MakeDirectory(macdir.c_str());
-    m_Makefile->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", target.GetName());
-    m_Makefile->ConfigureFile(f1.c_str(), f2.c_str(), false, false, false);
-    }
-#endif
-  std::string targetFullPath = outpath + targetName;
-  std::string targetFullPathReal = outpath + targetNameReal;
-
-  // Convert to the output path to use in constructing commands.
-  std::string targetOutPath =
-    this->Convert(targetFullPath.c_str(),START_OUTPUT,MAKEFILE);
-  std::string targetOutPathReal =
-    this->Convert(targetFullPathReal.c_str(),START_OUTPUT,MAKEFILE);
-
-  // Get the language to use for linking this executable.
-  const char* linkLanguage =
-    target.GetLinkerLanguage(this->GetGlobalGenerator());
-
-  // Make sure we have a link language.
-  if(!linkLanguage)
-    {
-    cmSystemTools::Error("Cannot determine link language for target \"",
-                         target.GetName(), "\".");
-    return;
-    }
-
-  // Add the link message.
-  std::string buildEcho = "Linking ";
-  buildEcho += linkLanguage;
-  buildEcho += " executable ";
-  buildEcho += targetOutPath;
-  this->AppendEcho(commands, buildEcho.c_str());
-
-  // Build a list of compiler flags and linker flags.
-  std::string flags;
-  std::string linkFlags;
-
-  // Add flags to deal with shared libraries.  Any library being
-  // linked in might be shared, so always use shared flags for an
-  // executable.
-  this->AddSharedFlags(linkFlags, linkLanguage, true);
-
-  // Add flags to create an executable.
-  this->AddConfigVariableFlags(linkFlags, "CMAKE_EXE_LINKER_FLAGS");
-
-
-  if(target.GetPropertyAsBool("WIN32_EXECUTABLE"))
-    {
-    this->AppendFlags(linkFlags,
-                      m_Makefile->GetDefinition("CMAKE_CREATE_WIN32_EXE"));
-    }
-  else
-    {
-    this->AppendFlags(linkFlags,
-                      m_Makefile->GetDefinition("CMAKE_CREATE_CONSOLE_EXE"));
-    }
-
-  // Add language-specific flags.
-  this->AddLanguageFlags(flags, linkLanguage);
-
-  // Add target-specific linker flags.
-  this->AppendFlags(linkFlags, target.GetProperty("LINK_FLAGS"));
-
-  // Construct a list of files associated with this executable that
-  // may need to be cleaned.
-  std::vector<std::string> exeCleanFiles;
-  {
-  std::string cleanName;
-  std::string cleanRealName;
-  target.GetExecutableCleanNames(cleanName, cleanRealName,
-                                 m_ConfigurationName.c_str());
-  std::string cleanFullName = outpath + cleanName;
-  std::string cleanFullRealName = outpath + cleanRealName;
-  exeCleanFiles.push_back
-    (this->Convert(cleanFullName.c_str(),START_OUTPUT,MAKEFILE));
-  if(cleanRealName != cleanName)
-    {
-    exeCleanFiles.push_back
-      (this->Convert(cleanFullRealName.c_str(),START_OUTPUT,MAKEFILE));
-    }
-  } 
-
-  // Add a command to remove any existing files for this executable.
-  std::vector<std::string> commands1;
-  this->AppendCleanCommand(commands1, exeCleanFiles);
-  this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
-                        m_Makefile->GetHomeOutputDirectory()); 
-  commands.insert(commands.end(), commands1.begin(), commands1.end());
-  commands1.clear();
-  // Add the pre-build and pre-link rules.
-  this->AppendCustomCommands(commands, target.GetPreBuildCommands());
-  this->AppendCustomCommands(commands, target.GetPreLinkCommands());
-
-  // Construct the main link rule.
-  std::string linkRuleVar = "CMAKE_";
-  linkRuleVar += linkLanguage;
-  linkRuleVar += "_LINK_EXECUTABLE";
-  std::string linkRule = 
-    m_Makefile->GetRequiredDefinition(linkRuleVar.c_str());
-  cmSystemTools::ExpandListArgument(linkRule, commands1);
-  this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
-                        m_Makefile->GetHomeOutputDirectory());
-  commands.insert(commands.end(), commands1.begin(), commands1.end());
-
-  // Add a rule to create necessary symlinks for the library.
-  if(targetOutPath != targetOutPathReal)
-    {
-    std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable ";
-    symlink += targetOutPathReal;
-    symlink += " ";
-    symlink += targetOutPath;
-    commands.push_back(symlink);
-    }
-
-  // Add the post-build rules.
-  this->AppendCustomCommands(commands, target.GetPostBuildCommands());
-
-  // Collect up flags to link in needed libraries.
-  cmOStringStream linklibs;
-  this->OutputLinkLibraries(linklibs, target);
-
-  // Construct object file lists that may be needed to expand the
-  // rule.
-  std::string variableName;
-  std::string variableNameExternal;
-  this->WriteObjectsVariable(ruleFileStream, target, objects, external_objects,
-                             variableName, variableNameExternal);
-  std::string buildObjs = "$(";
-  buildObjs += variableName;
-  buildObjs += ") $(";
-  buildObjs += variableNameExternal;
-  buildObjs += ")";
-  std::string cleanObjs = "$(";
-  cleanObjs += variableName;
-  cleanObjs += ")";
-
-  // Expand placeholders in the commands.
-  for(std::vector<std::string>::iterator i = commands.begin();
-      i != commands.end(); ++i)
-    {
-    this->ExpandRuleVariables(*i,
-                              linkLanguage,
-                              buildObjs.c_str(),
-                              targetOutPathReal.c_str(),
-                              linklibs.str().c_str(),
-                              0,
-                              0,
-                              flags.c_str(),
-                              0,
-                              0,
-                              linkFlags.c_str());
-    }
-
-  // Write the build rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      targetFullPathReal.c_str(), depends, commands);
-
-  // The symlink name for the target should depend on the real target
-  // so if the target version changes it rebuilds and recreates the
-  // symlink.
-  if(targetFullPath != targetFullPathReal)
-    {
-    depends.clear();
-    commands.clear();
-    depends.push_back(targetFullPathReal.c_str());
-    this->WriteMakeRule(ruleFileStream, 0,
-                        targetFullPath.c_str(), depends, commands);
-    }
-
-  // Write convenience targets.
-  std::string dir = m_Makefile->GetStartOutputDirectory();
-  dir += "/";
-  dir += this->GetTargetDirectory(target);
-  std::string buildTargetRuleName = dir;
-  buildTargetRuleName += "/build";
-  buildTargetRuleName = 
-    this->Convert(buildTargetRuleName.c_str(),HOME_OUTPUT,MAKEFILE);
-  this->WriteConvenienceRule(ruleFileStream, targetFullPath.c_str(),
-                             buildTargetRuleName.c_str());
-
-  // Clean all the possible executable names and symlinks and object files.
-  cleanFiles.insert(cleanFiles.end(),exeCleanFiles.begin(),exeCleanFiles.end());
-  cleanFiles.push_back(cleanObjs);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteStaticLibraryRule(std::ostream& ruleFileStream,
-                         const char* ruleFileName,
-                         cmTarget& target,
-                         const std::vector<std::string>& objects,
-                         const std::vector<std::string>& external_objects,
-                         std::vector<std::string>& cleanFiles)
-{
-  const char* linkLanguage =
-    target.GetLinkerLanguage(this->GetGlobalGenerator());
-  std::string linkRuleVar = "CMAKE_";
-  if (linkLanguage)
-    {
-    linkRuleVar += linkLanguage;
-    }
-  linkRuleVar += "_CREATE_STATIC_LIBRARY";
-
-  std::string extraFlags;
-  this->AppendFlags(extraFlags, target.GetProperty("STATIC_LIBRARY_FLAGS"));
-  this->WriteLibraryRule(ruleFileStream, ruleFileName, target,
-                         objects, external_objects,
-                         linkRuleVar.c_str(), extraFlags.c_str(),cleanFiles);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteSharedLibraryRule(std::ostream& ruleFileStream,
-                         const char* ruleFileName,
-                         cmTarget& target,
-                         const std::vector<std::string>& objects,
-                         const std::vector<std::string>& external_objects,
-                         std::vector<std::string>& cleanFiles)
-{
-  const char* linkLanguage =
-    target.GetLinkerLanguage(this->GetGlobalGenerator());
-  std::string linkRuleVar = "CMAKE_";
-  if (linkLanguage)
-    {
-    linkRuleVar += linkLanguage;
-    }
-  linkRuleVar += "_CREATE_SHARED_LIBRARY";
-
-  std::string extraFlags;
-  this->AppendFlags(extraFlags, target.GetProperty("LINK_FLAGS"));
-  this->AddConfigVariableFlags(extraFlags, "CMAKE_SHARED_LINKER_FLAGS");
-  if(m_Makefile->IsOn("WIN32") && !(m_Makefile->IsOn("CYGWIN") || m_Makefile->IsOn("MINGW")))
-    {
-    const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
-    for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
-        i != sources.end(); ++i)
-      {
-      if((*i)->GetSourceExtension() == "def")
-        {
-        extraFlags += " ";
-        extraFlags += m_Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
-        extraFlags += 
-          this->Convert((*i)->GetFullPath().c_str(),START_OUTPUT,MAKEFILE);
-        }
-      }
-    }
-  this->WriteLibraryRule(ruleFileStream, ruleFileName, target,
-                         objects, external_objects,
-                         linkRuleVar.c_str(), extraFlags.c_str(), cleanFiles);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteModuleLibraryRule(std::ostream& ruleFileStream,
-                         const char* ruleFileName,
-                         cmTarget& target,
-                         const std::vector<std::string>& objects,
-                         const std::vector<std::string>& external_objects,
-                         std::vector<std::string>& cleanFiles)
-{
-  const char* linkLanguage =
-    target.GetLinkerLanguage(this->GetGlobalGenerator());
-  std::string linkRuleVar = "CMAKE_";
-  if (linkLanguage)
-    {
-    linkRuleVar += linkLanguage;
-    }
-  linkRuleVar += "_CREATE_SHARED_MODULE";
-
-  std::string extraFlags;
-  this->AppendFlags(extraFlags, target.GetProperty("LINK_FLAGS"));
-  this->AddConfigVariableFlags(extraFlags, "CMAKE_MODULE_LINKER_FLAGS");
-  // TODO: .def files should be supported here also.
-  this->WriteLibraryRule(ruleFileStream, ruleFileName, target,
-                         objects, external_objects,
-                         linkRuleVar.c_str(), extraFlags.c_str(), cleanFiles);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteLibraryRule(std::ostream& ruleFileStream,
-                   const char* ruleFileName,
-                   cmTarget& target,
-                   const std::vector<std::string>& objects,
-                   const std::vector<std::string>& external_objects,
-                   const char* linkRuleVar,
-                   const char* extraFlags,
-                   std::vector<std::string>& cleanFiles)
-{
-  // Write the dependency generation rule.
-  this->WriteTargetDependRule(ruleFileStream, target);
-
-  // TODO: Merge the methods that call this method to avoid
-  // code duplication.
-  std::vector<std::string> commands;
-
-  std::string relPath = this->GetHomeRelativeOutputPath();
-  std::string objTarget;
-
-  // Build list of dependencies.
-  std::vector<std::string> depends;
-  for(std::vector<std::string>::const_iterator obj = objects.begin();
-      obj != objects.end(); ++obj)
-    {
-    objTarget = relPath;
-    objTarget += *obj;
-    depends.push_back(objTarget);
-    }
-
-  // Add dependencies on targets that must be built first.
-  this->AppendTargetDepends(depends, target);
-
-  // Add a dependency on the rule file itself.
-  this->AppendRuleDepend(depends, ruleFileName);
-
-  for(std::vector<std::string>::const_iterator obj = external_objects.begin();
-      obj != external_objects.end(); ++obj)
-    {
-    depends.push_back(*obj);
-    }
-
-  // from here up is the same for exe or lib
-
-  // Get the language to use for linking this library.
-  const char* linkLanguage =
-    target.GetLinkerLanguage(this->GetGlobalGenerator());
-
-  // Make sure we have a link language.
-  if(!linkLanguage)
-    {
-    cmSystemTools::Error("Cannot determine link language for target \"",
-                         target.GetName(), "\".");
-    return;
-    }
-
-  // Create set of linking flags.
-  std::string linkFlags;
-  this->AppendFlags(linkFlags, extraFlags);
-
-  // Construct the name of the library.
-  std::string targetName;
-  std::string targetNameSO;
-  std::string targetNameReal;
-  target.GetLibraryNames(targetName, targetNameSO, targetNameReal,
-                         m_ConfigurationName.c_str());
-
-  // Construct the full path version of the names.
-  std::string outpath = m_LibraryOutputPath;
-  if(outpath.length() == 0)
-    {
-    outpath = m_Makefile->GetStartOutputDirectory();
-    outpath += "/";
-    }
-  std::string targetFullPath = outpath + targetName;
-  std::string targetFullPathSO = outpath + targetNameSO;
-  std::string targetFullPathReal = outpath + targetNameReal;
-
-  // Construct the output path version of the names for use in command
-  // arguments.
-  std::string targetOutPath = 
-    this->Convert(targetFullPath.c_str(),START_OUTPUT,MAKEFILE);
-  std::string targetOutPathSO = 
-    this->Convert(targetFullPathSO.c_str(),START_OUTPUT,MAKEFILE);
-  std::string targetOutPathReal = 
-    this->Convert(targetFullPathReal.c_str(),START_OUTPUT,MAKEFILE);
-
-  // Add the link message.
-  std::string buildEcho = "Linking ";
-  buildEcho += linkLanguage;
-  switch(target.GetType())
-    {
-    case cmTarget::STATIC_LIBRARY:
-      buildEcho += " static library "; break;
-    case cmTarget::SHARED_LIBRARY:
-      buildEcho += " shared library "; break;
-    case cmTarget::MODULE_LIBRARY:
-      buildEcho += " shared module "; break;
-    default:
-      buildEcho += " library "; break;
-    }
-  buildEcho += targetOutPath.c_str();
-  this->AppendEcho(commands, buildEcho.c_str());
-
-  // Construct a list of files associated with this library that may
-  // need to be cleaned.
-  std::vector<std::string> libCleanFiles;
-  {
-  std::string cleanStaticName;
-  std::string cleanSharedName;
-  std::string cleanSharedSOName;
-  std::string cleanSharedRealName;
-  target.GetLibraryCleanNames(cleanStaticName,
-                              cleanSharedName,
-                              cleanSharedSOName,
-                              cleanSharedRealName,
-                              m_ConfigurationName.c_str());
-  std::string cleanFullStaticName = outpath + cleanStaticName;
-  std::string cleanFullSharedName = outpath + cleanSharedName;
-  std::string cleanFullSharedSOName = outpath + cleanSharedSOName;
-  std::string cleanFullSharedRealName = outpath + cleanSharedRealName;
-  libCleanFiles.push_back
-    (this->Convert(cleanFullStaticName.c_str(),START_OUTPUT,MAKEFILE));
-  if(cleanSharedRealName != cleanStaticName)
-    {
-    libCleanFiles.push_back
-      (this->Convert(cleanFullSharedRealName.c_str(),START_OUTPUT,MAKEFILE));
-    }
-  if(cleanSharedSOName != cleanStaticName &&
-     cleanSharedSOName != cleanSharedRealName)
-    {
-    libCleanFiles.push_back
-      (this->Convert(cleanFullSharedSOName.c_str(),START_OUTPUT,MAKEFILE));
-    }
-  if(cleanSharedName != cleanStaticName &&
-     cleanSharedName != cleanSharedSOName &&
-     cleanSharedName != cleanSharedRealName)
-    {
-    libCleanFiles.push_back
-      (this->Convert(cleanFullSharedName.c_str(),START_OUTPUT,MAKEFILE));
-    }
-  }
-  // Add a command to remove any existing files for this library.
-  std::vector<std::string> commands1;
-  this->AppendCleanCommand(commands1, libCleanFiles);
-  this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
-                        m_Makefile->GetHomeOutputDirectory());
-  commands.insert(commands.end(), commands1.begin(), commands1.end());
-  commands1.clear();
-  // Add the pre-build and pre-link rules.
-  this->AppendCustomCommands(commands, target.GetPreBuildCommands());
-  this->AppendCustomCommands(commands, target.GetPreLinkCommands());
-
-  // Construct the main link rule.
-  std::string linkRule = m_Makefile->GetRequiredDefinition(linkRuleVar);
-  cmSystemTools::ExpandListArgument(linkRule, commands1);
-  this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
-                        m_Makefile->GetHomeOutputDirectory());
-  commands.insert(commands.end(), commands1.begin(), commands1.end());
-
-  // Add a rule to create necessary symlinks for the library.
-  if(targetOutPath != targetOutPathReal)
-    {
-    std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
-    symlink += targetOutPathReal;
-    symlink += " ";
-    symlink += targetOutPathSO;
-    symlink += " ";
-    symlink += targetOutPath;
-    commands1.clear();
-    commands1.push_back(symlink);
-    this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
-                          m_Makefile->GetHomeOutputDirectory());
-    commands.insert(commands.end(), commands1.begin(), commands1.end());
-    }
-
-  // Add the post-build rules.
-  this->AppendCustomCommands(commands, target.GetPostBuildCommands());
-
-  // Collect up flags to link in needed libraries.
-  cmOStringStream linklibs;
-  this->OutputLinkLibraries(linklibs, target);
-
-  // Construct object file lists that may be needed to expand the
-  // rule.
-  std::string variableName;
-  std::string variableNameExternal;
-  this->WriteObjectsVariable(ruleFileStream, target, objects, external_objects,
-                             variableName, variableNameExternal);
-  std::string buildObjs = "$(";
-  buildObjs += variableName;
-  buildObjs += ") $(";
-  buildObjs += variableNameExternal;
-  buildObjs += ")";
-  std::string cleanObjs = "$(";
-  cleanObjs += variableName;
-  cleanObjs += ")";
-
-  // Expand placeholders in the commands.
-  for(std::vector<std::string>::iterator i = commands.begin();
-      i != commands.end(); ++i)
-    {
-    this->ExpandRuleVariables(*i,
-                              linkLanguage,
-                              buildObjs.c_str(),
-                              targetOutPathReal.c_str(),
-                              linklibs.str().c_str(),
-                              0, 0, 0, buildObjs.c_str(),
-                              targetNameSO.c_str(),
-                              linkFlags.c_str());
-    }
-
-  // Write the build rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      targetFullPathReal.c_str(), depends, commands);
-
-  // The symlink names for the target should depend on the real target
-  // so if the target version changes it rebuilds and recreates the
-  // symlinks.
-  if(targetFullPathSO != targetFullPathReal)
-    {
-    depends.clear();
-    commands.clear();
-    depends.push_back(targetFullPathReal.c_str());
-    this->WriteMakeRule(ruleFileStream, 0,
-                        targetFullPathSO.c_str(), depends, commands);
-    }
-  if(targetFullPath != targetFullPathSO)
-    {
-    depends.clear();
-    commands.clear();
-    depends.push_back(targetFullPathSO.c_str());
-    this->WriteMakeRule(ruleFileStream, 0,
-                        targetFullPath.c_str(), depends, commands);
-    }
-
-  // Write convenience targets.
-  std::string dir = m_Makefile->GetStartOutputDirectory();
-  dir += "/";
-  dir += this->GetTargetDirectory(target);
-  std::string buildTargetRuleName = dir;
-  buildTargetRuleName += "/build";
-  buildTargetRuleName = 
-    this->Convert(buildTargetRuleName.c_str(),HOME_OUTPUT,MAKEFILE);
-  this->WriteConvenienceRule(ruleFileStream, targetFullPath.c_str(),
-                             buildTargetRuleName.c_str());
-
-  // Clean all the possible library names and symlinks and object files.
-  cleanFiles.insert(cleanFiles.end(),libCleanFiles.begin(),libCleanFiles.end());
-  cleanFiles.push_back(cleanObjs);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteObjectsVariable(std::ostream& ruleFileStream,
-                       cmTarget& target,
-                       const std::vector<std::string>& objects,
-                       const std::vector<std::string>& external_objects,
-                       std::string& variableName,
-                       std::string& variableNameExternal)
-{
-  // Write a make variable assignment that lists all objects for the
-  // target.
-  variableName = this->CreateMakeVariable(target.GetName(), "_OBJECTS");
-  ruleFileStream
-    << "# Object files for target " << target.GetName() << "\n"
-    << variableName.c_str() << " =";
-  std::string object;
-  const char* objName =  m_Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS");
-  const char* lineContinue = m_Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE");
-  if(!lineContinue)
-    {
-    lineContinue = "\\";
-    }
-  for(std::vector<std::string>::const_iterator i = objects.begin();
-      i != objects.end(); ++i)
-    {
-    ruleFileStream
-      << " " << lineContinue << "\n";
-    if(objName)
-      {
-      ruleFileStream  << this->Convert(i->c_str(), START_OUTPUT, MAKEFILE);
-      }
-    else
-      {
-      ruleFileStream  << this->ConvertToQuotedOutputPath(i->c_str());
-      }
-    }
-  ruleFileStream
-    << "\n";
-
-  // Write a make variable assignment that lists all external objects
-  // for the target.
-  variableNameExternal = this->CreateMakeVariable(target.GetName(),
-                                                  "_EXTERNAL_OBJECTS");
-  ruleFileStream
-    << "\n"
-    << "# External object files for target " << target.GetName() << "\n"
-    << variableNameExternal.c_str() << " =";
-  for(std::vector<std::string>::const_iterator i = external_objects.begin();
-      i != external_objects.end(); ++i)
-    {
-    object = this->Convert(i->c_str(),START_OUTPUT);
-    ruleFileStream
-      << " " << lineContinue << "\n"
-      << m_Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME");
-    if(objName)
-      {
-      ruleFileStream  << this->Convert(i->c_str(), START_OUTPUT, MAKEFILE);
-      }
-    else
-      {
-      ruleFileStream  << this->ConvertToQuotedOutputPath(i->c_str());
-      }
-    }
-  ruleFileStream
-    << "\n"
-    << "\n";
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteTargetDependRule(std::ostream& ruleFileStream, cmTarget& target)
-{
-  // must write the targets depend info file
-  std::string dir = this->GetTargetDirectory(target);
-  std::string infoFileName = dir;
-  infoFileName += "/DependInfo.cmake";
-  std::string ruleFileNameFull = this->ConvertToFullPath(infoFileName);
-  cmGeneratedFileStream infoFileStream(ruleFileNameFull.c_str());
-  infoFileStream.SetCopyIfDifferent(true);
-  if(!infoFileStream)
-    {
-    return;
-    }
-  this->WriteDependLanguageInfo(infoFileStream,target);
-  
-  // and now write the rule to use it
-  std::vector<std::string> depends;
-  std::vector<std::string> commands;
-
-  // Construct the name of the dependency generation target.
-  std::string depTarget = this->GetRelativeTargetDirectory(target);
-  depTarget += "/depend";
-  
-  std::string depMark = depTarget;
-  depMark += ".make.mark";
-  depends.push_back(depMark);
-  
-  this->WriteMakeRule(ruleFileStream, 0,
-                      depTarget.c_str(), depends, commands);
-  depends.clear();
-  
-  // Write the dependency generation rule.
-  std::string depEcho = "Scanning dependencies of target ";
-  depEcho += target.GetName();
-  this->AppendEcho(commands, depEcho.c_str());
-  
-  // Add a command to call CMake to scan dependencies.  CMake will
-  // touch the corresponding depends file after scanning dependencies.
-  cmOStringStream depCmd;
-  // TODO: Account for source file properties and directory-level
-  // definitions when scanning for dependencies.
-  depCmd << "$(CMAKE_COMMAND) -E cmake_depends " 
-         << " \""
-         << m_GlobalGenerator->GetName() << "\" "
-         << this->Convert(m_Makefile->GetHomeOutputDirectory(),FULL,SHELL)
-         << " "
-         << this->Convert(m_Makefile->GetStartOutputDirectory(),FULL,SHELL)
-         << " "
-         << this->Convert(ruleFileNameFull.c_str(),FULL,SHELL);
-  commands.push_back(depCmd.str());
-  
-  // Write the rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      depMark.c_str(), depends, commands);
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteTargetCleanRule(std::ostream& ruleFileStream,
-                       cmTarget& target,
-                       const std::vector<std::string>& files)
-{
-  std::vector<std::string> depends;
-  const char* sym = m_Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE");
-  if(sym)
-    {
-    depends.push_back(sym);
-    }
-  std::vector<std::string> commands;
-
-  // Construct the clean target name.
-  std::string cleanTarget = this->GetRelativeTargetDirectory(target);
-  cleanTarget += "/clean";
-  
-  // Construct the clean command.
-  this->AppendCleanCommand(commands, files);
-  this->CreateCDCommand(commands,m_Makefile->GetStartOutputDirectory(),
-                        m_Makefile->GetHomeOutputDirectory());
-  // Write the rule.
-  this->WriteMakeRule(ruleFileStream, 0,
-                      cleanTarget.c_str(), depends, commands);
-}
-
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::WriteCMakeArgument(std::ostream& os, const char* s)
-{
-  // Write the given string to the stream with escaping to get it back
-  // into CMake through the lexical scanner.
-  os << "\"";
-  for(const char* c = s; *c; ++c)
-    {
-    if(*c == '\\')
-      {
-      os << "\\\\";
-      }
-    else if(*c == '"')
-      {
-      os << "\\\"";
-      }
-    else
-      {
-      os << *c;
-      }
-    }
-  os << "\"";
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalUnixMakefileGenerator3::GetTargetDirectory(cmTarget& target)
-{
-  std::string dir = "CMakeFiles/";
-  dir += target.GetName();
-  dir += ".dir";
-  return dir;
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(cmTarget& target)
-{
-  std::string dir = m_Makefile->GetStartOutputDirectory();
-  dir += "/";
-  dir += this->GetTargetDirectory(target);
-  dir = cmSystemTools::RelativePath(m_Makefile->GetHomeOutputDirectory(), dir.c_str());
-  return this->Convert(dir.c_str(),NONE,MAKEFILE);
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalUnixMakefileGenerator3
-::GetObjectFileName(cmTarget& target,
-                    const cmSourceFile& source,
-                    std::string* nameWithoutTargetDir)
-{
-  // If the full path to the source file includes this directory,
-  // we want to use the relative path for the filename of the
-  // object file.  Otherwise, we will use just the filename
-  // portion.
-  std::string objectName;
-  if((cmSystemTools::GetFilenamePath(
-        source.GetFullPath()).find(
-          m_Makefile->GetCurrentDirectory()) == 0)
-     || (cmSystemTools::GetFilenamePath(
-           source.GetFullPath()).find(
-             m_Makefile->GetStartOutputDirectory()) == 0))
-    {
-    objectName = source.GetSourceName();
-    }
-  else
-    {
-    objectName = cmSystemTools::GetFilenameName(source.GetSourceName());
-    }
-
-  // Append the object file extension.
-  objectName +=
-    m_GlobalGenerator->GetLanguageOutputExtensionFromExtension(
-      source.GetSourceExtension().c_str());
-
-  // Convert to a safe name.
-  objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str());
-  // Prepend the target directory.
-  std::string obj = this->GetTargetDirectory(target);
-  obj += "/";
-  obj += objectName;
-  if(nameWithoutTargetDir)
-    {
-    *nameWithoutTargetDir = objectName;
-    }
-  return obj;
-}
-
-//----------------------------------------------------------------------------
-const char*
-cmLocalUnixMakefileGenerator3
-::GetSourceFileLanguage(const cmSourceFile& source)
-{
-  // Identify the language of the source file.
-  return (m_GlobalGenerator
-          ->GetLanguageFromExtension(source.GetSourceExtension().c_str()));
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
-{
-  
-  // Split the path into its components.
-  std::vector<std::string> components;
-  cmSystemTools::SplitPath(p, components);
-
-  // Return an empty path if there are no components.
-  if(components.empty())
-    {
-    return "\"\"";
-    }
-
-  // Choose a slash direction and fix root component.
-  const char* slash = "/";
-#if defined(_WIN32) && !defined(__CYGWIN__)
-   if(!cmSystemTools::GetForceUnixPaths())
-     {
-     slash = "\\";
-     for(std::string::iterator i = components[0].begin();
-       i != components[0].end(); ++i)
-       {
-       if(*i == '/')
-         {
-         *i = '\\';
-         }
-       }
-     }
-#endif
-
-  // Begin the quoted result with the root component.
-  std::string result = "\"";
-  result += components[0];
-
-  // Now add the rest of the components separated by the proper slash
-  // direction for this platform.
-  bool first = true;
-  for(unsigned int i=1; i < components.size(); ++i)
-    {
-    // Only the last component can be empty to avoid double slashes.
-    if(components[i].length() > 0 || (i == (components.size()-1)))
-      {
-      if(!first)
-        {
-        result += slash;
-        }
-      result += components[i];
-      first = false;
-      }
-    }
-
-  // Close the quoted result.
-  result += "\"";
-
-  return result;
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::AppendTargetDepends(std::vector<std::string>& depends,
-                      cmTarget& target)
-{
-  // Static libraries never depend on anything for linking.
-  if(target.GetType() == cmTarget::STATIC_LIBRARY)
-    {
-    return;
-    }
-
-  // Keep track of dependencies already listed.
-  std::set<cmStdString> emitted;
-
-  // A target should not depend on itself.
-  emitted.insert(target.GetName());
-
-  // Loop over all library dependencies.
-  const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries();
-  for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
-      lib != tlibs.end(); ++lib)
-    {
-    // Don't emit the same library twice for this target.
-    if(emitted.insert(lib->first).second)
-      {
-      // Depend only on other CMake targets.
-      if(cmTarget* tgt = m_GlobalGenerator->FindTarget(0, lib->first.c_str()))
-        {
-        if(const char* location =
-           tgt->GetLocation(m_ConfigurationName.c_str()))
-          {
-          depends.push_back(location);
-          }
-        }
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::AppendRuleDepend(std::vector<std::string>& depends,
-                   const char* ruleFileName)
-{
-  // Add a dependency on the rule file itself unless an option to skip
-  // it is specifically enabled by the user or project.
-  const char* nodep = m_Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
-  if(!nodep || cmSystemTools::IsOff(nodep))
-    {
-    depends.push_back(ruleFileName);
-    }
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::AppendCustomDepends(std::vector<std::string>& depends,
-                      const std::vector<cmCustomCommand>& ccs)
-{
-  for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
-      i != ccs.end(); ++i)
-    {
-    this->AppendCustomDepend(depends, *i);
-    }
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::AppendCustomDepend(std::vector<std::string>& depends,
-                     const cmCustomCommand& cc)
-{
-  for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
-      d != cc.GetDepends().end(); ++d)
-    {
-    // Lookup the real name of the dependency in case it is a CMake target.
-    std::string dep = this->GetRealDependency(d->c_str(),
-                                              m_ConfigurationName.c_str());
-    depends.push_back(dep);
-    }
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator3
-::AppendCustomCommands(std::vector<std::string>& commands,
-                       const std::vector<cmCustomCommand>& ccs)
-{
-  for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
-      i != ccs.end(); ++i)
-    {
-    this->AppendCustomCommand(commands, *i);
+    this->AppendCustomCommand(commands, *i);
     }
 }
 
@@ -2410,15 +926,15 @@ cmLocalUnixMakefileGenerator3
     }
 
   // push back the custom commands
-  const char* dir  =m_Makefile->GetStartOutputDirectory();
+  const char* dir  = m_Makefile->GetStartOutputDirectory();
   // if the command specified a working directory use it.
   if(cc.GetWorkingDirectory())
     {
     dir = cc.GetWorkingDirectory();
     }
-  
   this->CreateCDCommand(commands1, dir,
                         m_Makefile->GetHomeOutputDirectory());
+
   commands.insert(commands.end(), commands1.begin(), commands1.end());
 }
 
@@ -2514,7 +1030,8 @@ cmLocalUnixMakefileGenerator3::CreateSafeUniqueObjectFileName(const char* sin)
 {
   if ( m_Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES") )
     {
-    std::map<cmStdString,cmStdString>::iterator it = m_UniqueObjectNamesMap.find(sin);
+    std::map<cmStdString,cmStdString>::iterator it = 
+      m_UniqueObjectNamesMap.find(sin);
     if ( it == m_UniqueObjectNamesMap.end() )
       {
       std::string ssin = sin;
@@ -2870,11 +1387,11 @@ void cmLocalUnixMakefileGenerator3
     dir = "all";
     depends.push_back("cmake_check_build_system");
     }
-  commands.push_back(this->GetRecursiveMakeCall
-                     ("CMakeFiles/Makefile2",dir.c_str()));  
+  commands.push_back
+    (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str()));  
   this->CreateCDCommand(commands,
-                        m_Makefile->GetHomeOutputDirectory(),
-                        m_Makefile->GetStartOutputDirectory());
+                                m_Makefile->GetHomeOutputDirectory(),
+                                m_Makefile->GetStartOutputDirectory());
   this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands);
 
   // Write the clean rule.
@@ -2887,11 +1404,11 @@ void cmLocalUnixMakefileGenerator3
     {
     depends.push_back(sym);
     }
-  commands.push_back(this->GetRecursiveMakeCall
-                     ("CMakeFiles/Makefile2",dir.c_str()));  
+  commands.push_back
+    (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str()));  
   this->CreateCDCommand(commands,
-                        m_Makefile->GetHomeOutputDirectory(),
-                        m_Makefile->GetStartOutputDirectory());
+                                m_Makefile->GetHomeOutputDirectory(),
+                                m_Makefile->GetStartOutputDirectory());
   this->WriteMakeRule(ruleFileStream, "The main clean target", "clean", depends, commands);
 
   // write the depend rule, really a recompute depends rule
@@ -2916,133 +1433,292 @@ void cmLocalUnixMakefileGenerator3
                       depends, commands);
 }
 
+
 //----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
+void cmLocalUnixMakefileGenerator3::CheckDependencies(cmMakefile* mf, 
+                                                      bool verbose,
+                                                      bool clear)
 {
-  // generate the includes
-  std::string ruleFileName = "Makefile";
-
-  // Open the rule file.  This should be copy-if-different because the
-  // rules may depend on this file itself.
-  std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
-  cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
-  if(!ruleFileStream)
+  // Get the list of target files to check
+  const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES");
+  if(!infoDef)
     {
     return;
     }
-  // always write the top makefile
-  if (m_Parent)
+  std::vector<std::string> files;
+  cmSystemTools::ExpandListArgument(infoDef, files);
+
+  // For each info file run the check
+  cmDependsC checker;
+  checker.SetVerbose(verbose);
+  checker.SetFileComparison(m_GlobalGenerator->GetCMakeInstance()->GetFileComparison());
+  for(std::vector<std::string>::iterator l = files.begin();
+      l != files.end(); ++l)
     {
-    ruleFileStream.SetCopyIfDifferent(true);
+    // either clear or check the files
+    std::string dir = cmSystemTools::GetFilenamePath(l->c_str());
+    std::string internalDependFile = dir + "/depend.internal";
+    std::string dependFile = dir + "/depend.make";
+    if (clear)
+      {
+      checker.Clear(internalDependFile.c_str());
+      checker.Clear(dependFile.c_str());
+      }
+    else
+      {
+      checker.Check(dependFile.c_str(), internalDependFile.c_str());
+      }
+    }
+}
+
+
+void cmLocalUnixMakefileGenerator3
+::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)
+{
+  // now write all the language stuff
+  // Set the set of files to check for dependency integrity.
+  std::set<cmStdString> checkSetLangs;
+  std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& 
+    checkSet = this->GetIntegrityCheckSet()[target.GetName()];
+  for(std::map<cmStdString, 
+        cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
+        l = checkSet.begin(); l != checkSet.end(); ++l)
+    {
+    checkSetLangs.insert(l->first);
     }
   
-  // write the all rules
-  this->WriteLocalAllRules(ruleFileStream);
+  // list the languages
+  cmakefileStream
+    << "# The set of files whose dependency integrity should be checked:\n";
+  cmakefileStream
+    << "SET(CMAKE_DEPENDS_LANGUAGES\n";
+  for(std::set<cmStdString>::iterator
+        l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
+    {
+    cmakefileStream << "  \"" << l->c_str() << "\"\n";
+    }
+  cmakefileStream << "  )\n";
   
-  // only write local targets unless at the top Keep track of targets already
-  // listed.
-  std::set<cmStdString> emittedTargets;
-  if (m_Parent)
+  // now list the files for each language
+  for(std::set<cmStdString>::iterator
+        l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
     {
-    // write our targets, and while doing it collect up the object
-    // file rules
-    this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets);
+    cmakefileStream
+      << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n";
+    // get the check set for this local gen and language
+    cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet = 
+      checkSet[*l];
+    // for each file
+    for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator 
+          csIter = iCheckSet.begin();
+        csIter != iCheckSet.end(); ++csIter)
+      {
+      cmakefileStream << "  \"" << (*csIter)->GetFullPath() << "\"\n";
+      // Get the full path name of the object file.
+      std::string obj = m_Makefile->GetStartOutputDirectory();
+      obj += "/";
+      obj += this->GetObjectFileName(target, **csIter);
+      cmakefileStream << "  \"" << 
+        this->Convert(obj.c_str(),
+                      cmLocalGenerator::FULL).c_str() << "\"\n";
+      }
+    cmakefileStream << "  )\n";
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::GetObjectFileName(cmTarget& target,
+                    const cmSourceFile& source,
+                    std::string* nameWithoutTargetDir)
+{
+  // If the full path to the source file includes this directory,
+  // we want to use the relative path for the filename of the
+  // object file.  Otherwise, we will use just the filename
+  // portion.
+  std::string objectName;
+  if((cmSystemTools::GetFilenamePath(
+        source.GetFullPath()).find(
+          m_Makefile->GetCurrentDirectory()) == 0)
+     || (cmSystemTools::GetFilenamePath(
+           source.GetFullPath()).find(
+             m_Makefile->GetStartOutputDirectory()) == 0))
+    {
+    objectName = source.GetSourceName();
     }
   else
     {
-    cmGlobalUnixMakefileGenerator3 *gg = 
-      static_cast<cmGlobalUnixMakefileGenerator3*>(m_GlobalGenerator);
-    gg->WriteConvenienceRules(ruleFileStream,emittedTargets);
+    objectName = cmSystemTools::GetFilenameName(source.GetSourceName());
+    }
+
+  // Append the object file extension.
+  objectName +=
+    m_GlobalGenerator->GetLanguageOutputExtensionFromExtension(
+      source.GetSourceExtension().c_str());
+
+  // Convert to a safe name.
+  objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str());
+  // Prepend the target directory.
+  std::string obj = this->GetTargetDirectory(target);
+  obj += "/";
+  obj += objectName;
+  if(nameWithoutTargetDir)
+    {
+    *nameWithoutTargetDir = objectName;
     }
+  return obj;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
+{
+  os
+    << "# CMAKE generated file: DO NOT EDIT!\n"
+    << "# Generated by \"" << m_GlobalGenerator->GetName() << "\""
+    << " Generator, CMake Version "
+    << cmMakefile::GetMajorVersion() << "."
+    << cmMakefile::GetMinorVersion() << "\n\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::GetRecursiveMakeCall(const char *Makefile, const char* tgt)
+{
+  // Call make on the given file.
+  std::string cmd;
+  cmd += "$(MAKE) -f ";
+  cmd += Makefile;
+  cmd += " ";
   
-  std::vector<std::string> depends;
-  std::vector<std::string> commands;
+  // Passg down verbosity level.
+  if(this->GetMakeSilentFlag().size())
+    {
+    cmd += this->GetMakeSilentFlag();
+    cmd += " ";
+    }
 
-  // now write out the object rules
-  // for each object file name
-  for (std::map<cmStdString,std::vector<cmTarget *> >::iterator lo = 
-         m_LocalObjectFiles.begin();
-       lo != m_LocalObjectFiles.end(); ++lo)
+  // Most unix makes will pass the command line flags to make down to
+  // sub-invoked makes via an environment variable.  However, some
+  // makes do not support that, so you have to pass the flags
+  // explicitly.
+  if(this->GetPassMakeflags())
     {
-    commands.clear();
-    // for each target using the object file
-    for (std::vector<cmTarget *>::iterator to = 
-           lo->second.begin(); to != lo->second.end(); ++to)
+    cmd += "-$(MAKEFLAGS) ";
+    }
+
+  // Add the target.
+  if (tgt && tgt[0] != '\0')
+    {
+    std::string tgt2 = this->Convert(tgt,HOME_OUTPUT,MAKEFILE);
+    tgt2 = this->ConvertToMakeTarget(tgt2.c_str());
+    cmd += tgt2;
+    }
+  return cmd;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
+{
+  os
+    << "#======================================"
+    << "=======================================\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteCMakeArgument(std::ostream& os, const char* s)
+{
+  // Write the given string to the stream with escaping to get it back
+  // into CMake through the lexical scanner.
+  os << "\"";
+  for(const char* c = s; *c; ++c)
+    {
+    if(*c == '\\')
       {
-      std::string tgtMakefileName = this->GetRelativeTargetDirectory(**to);
-      std::string targetName = tgtMakefileName;
-      tgtMakefileName += "/build.make";
-      targetName += "/";
-      targetName += lo->first.c_str();
-      commands.push_back(this->GetRecursiveMakeCall
-                         (tgtMakefileName.c_str(),targetName.c_str()));  
-      this->CreateCDCommand(commands,
-                            m_Makefile->GetHomeOutputDirectory(),
-                            m_Makefile->GetStartOutputDirectory());
+      os << "\\\\";
+      }
+    else if(*c == '"')
+      {
+      os << "\\\"";
+      }
+    else
+      {
+      os << *c;
       }
-    this->WriteMakeRule(ruleFileStream, 
-                        "target for object file", 
-                        lo->first.c_str(), depends, commands);
     }
+  os << "\"";
+}
 
-  // add a help target as long as there isn;t a real target named help
-  if(emittedTargets.insert("help").second)
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
+{
+  
+  // Split the path into its components.
+  std::vector<std::string> components;
+  cmSystemTools::SplitPath(p, components);
+
+  // Return an empty path if there are no components.
+  if(components.empty())
     {
-    cmGlobalUnixMakefileGenerator3 *gg = 
-      static_cast<cmGlobalUnixMakefileGenerator3*>(m_GlobalGenerator);
-    gg->WriteHelpRule(ruleFileStream,this);
+    return "\"\"";
     }
 
-  this->WriteSpecialTargetsBottom(ruleFileStream);
-}
+  // Choose a slash direction and fix root component.
+  const char* slash = "/";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+   if(!cmSystemTools::GetForceUnixPaths())
+     {
+     slash = "\\";
+     for(std::string::iterator i = components[0].begin();
+       i != components[0].end(); ++i)
+       {
+       if(*i == '/')
+         {
+         *i = '\\';
+         }
+       }
+     }
+#endif
 
-void cmLocalUnixMakefileGenerator3
-::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
-                            std::set<cmStdString> &emitted)
-{
-  std::vector<std::string> depends;
-  std::vector<std::string> commands;
+  // Begin the quoted result with the root component.
+  std::string result = "\"";
+  result += components[0];
 
-  // for each target we just provide a rule to cd up to the top and do a make
-  // on the target
-  cmTargets& targets = m_Makefile->GetTargets();
-  std::string localName;
-  for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+  // Now add the rest of the components separated by the proper slash
+  // direction for this platform.
+  bool first = true;
+  for(unsigned int i=1; i < components.size(); ++i)
     {
-    if((t->second.GetType() == cmTarget::EXECUTABLE) ||
-       (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
-       (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
-       (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
-       (t->second.GetType() == cmTarget::UTILITY))
+    // Only the last component can be empty to avoid double slashes.
+    if(components[i].length() > 0 || (i == (components.size()-1)))
       {
-      emitted.insert(t->second.GetName());
-
-      // for subdirs add a rule to build this specific target by name.
-      localName = this->GetRelativeTargetDirectory(t->second);
-      localName += "/rule";
-      commands.clear();
-      depends.clear();
-      
-      // Build the target for this pass.
-      commands.push_back(this->GetRecursiveMakeCall
-                         ("CMakeFiles/Makefile2",localName.c_str()));
-      
-      this->CreateCDCommand(commands,
-                            m_Makefile->GetHomeOutputDirectory(),
-                            m_Makefile->GetStartOutputDirectory());
-      this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
-                          localName.c_str(), depends, commands);
-      
-      // Add a target with the canonical name (no prefix, suffix or path).
-      if(localName != t->second.GetName())
+      if(!first)
         {
-        commands.clear();
-        depends.push_back(localName);
-        this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
-                          t->second.GetName(), depends, commands);
+        result += slash;
         }
+      result += components[i];
+      first = false;
       }
     }
+
+  // Close the quoted result.
+  result += "\"";
+
+  return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3::GetTargetDirectory(cmTarget& target)
+{
+  std::string dir = "CMakeFiles/";
+  dir += target.GetName();
+  dir += ".dir";
+  return dir;
 }
 
 void cmLocalUnixMakefileGenerator3
@@ -3093,130 +1769,12 @@ void cmLocalUnixMakefileGenerator3
 }
 
 //----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::CheckDependencies(cmMakefile* mf, 
-                                                      bool verbose,
-                                                      bool clear)
-{
-  // Get the list of target files to check
-  const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES");
-  if(!infoDef)
-    {
-    return;
-    }
-  std::vector<std::string> files;
-  cmSystemTools::ExpandListArgument(infoDef, files);
-
-  // For each info file run the check
-  cmDependsC checker;
-  checker.SetVerbose(verbose);
-  checker.SetFileComparison(m_GlobalGenerator->GetCMakeInstance()->GetFileComparison());
-  for(std::vector<std::string>::iterator l = files.begin();
-      l != files.end(); ++l)
-    {
-    // either clear or check the files
-    std::string dir = cmSystemTools::GetFilenamePath(l->c_str());
-    std::string internalDependFile = dir + "/depend.internal";
-    std::string dependFile = dir + "/depend.make";
-    if (clear)
-      {
-      checker.Clear(internalDependFile.c_str());
-      checker.Clear(dependFile.c_str());
-      }
-    else
-      {
-      checker.Check(dependFile.c_str(), internalDependFile.c_str());
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-std::string
+const char*
 cmLocalUnixMakefileGenerator3
-::GetRecursiveMakeCall(const char *Makefile, const char* tgt)
+::GetSourceFileLanguage(const cmSourceFile& source)
 {
-  // Call make on the given file.
-  std::string cmd;
-  cmd += "$(MAKE) -f ";
-  cmd += Makefile;
-  cmd += " ";
-  
-  // Passg down verbosity level.
-  if(this->GetMakeSilentFlag().size())
-    {
-    cmd += this->GetMakeSilentFlag();
-    cmd += " ";
-    }
-
-  // Most unix makes will pass the command line flags to make down to
-  // sub-invoked makes via an environment variable.  However, some
-  // makes do not support that, so you have to pass the flags
-  // explicitly.
-  if(this->GetPassMakeflags())
-    {
-    cmd += "-$(MAKEFLAGS) ";
-    }
-
-  // Add the target.
-  if (tgt && tgt[0] != '\0')
-    {
-    std::string tgt2 = this->Convert(tgt,HOME_OUTPUT,MAKEFILE);
-    tgt2 = this->ConvertToMakeTarget(tgt2.c_str());
-    cmd += tgt2;
-    }
-  return cmd;
+  // Identify the language of the source file.
+  return (m_GlobalGenerator
+          ->GetLanguageFromExtension(source.GetSourceExtension().c_str()));
 }
 
-
-void cmLocalUnixMakefileGenerator3
-::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)
-{
-  // now write all the language stuff
-  // Set the set of files to check for dependency integrity.
-  std::set<cmStdString> checkSetLangs;
-  std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& 
-    checkSet = this->GetIntegrityCheckSet()[target.GetName()];
-  for(std::map<cmStdString, 
-        cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
-        l = checkSet.begin(); l != checkSet.end(); ++l)
-    {
-    checkSetLangs.insert(l->first);
-    }
-  
-  // list the languages
-  cmakefileStream
-    << "# The set of files whose dependency integrity should be checked:\n";
-  cmakefileStream
-    << "SET(CMAKE_DEPENDS_LANGUAGES\n";
-  for(std::set<cmStdString>::iterator
-        l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
-    {
-    cmakefileStream << "  \"" << l->c_str() << "\"\n";
-    }
-  cmakefileStream << "  )\n";
-  
-  // now list the files for each language
-  for(std::set<cmStdString>::iterator
-        l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
-    {
-    cmakefileStream
-      << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n";
-    // get the check set for this local gen and language
-    cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet = 
-      checkSet[*l];
-    // for each file
-    for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator 
-          csIter = iCheckSet.begin();
-        csIter != iCheckSet.end(); ++csIter)
-      {
-      cmakefileStream << "  \"" << (*csIter)->GetFullPath() << "\"\n";
-      // Get the full path name of the object file.
-      std::string obj = m_Makefile->GetStartOutputDirectory();
-      obj += "/";
-      obj += this->GetObjectFileName(target, **csIter);
-      cmakefileStream << "  \"" << 
-        this->Convert(obj.c_str(),
-                      cmLocalGenerator::FULL).c_str() << "\"\n";
-      }
-    cmakefileStream << "  )\n";
-    }
-}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index b0d2599..1f873ce 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -23,6 +23,7 @@ class cmCustomCommand;
 class cmDependInformation;
 class cmDepends;
 class cmMakeDepend;
+class cmMakefileTargetGenerator;
 class cmTarget;
 class cmSourceFile;
 
@@ -39,19 +40,29 @@ public:
   virtual ~cmLocalUnixMakefileGenerator3();
 
   /**
-   * Generate the makefile for this directory. 
-   */
-  virtual void Generate();
-
-  /**
    * Process the CMakeLists files for this directory to fill in the
    * m_Makefile ivar 
    */
   virtual void Configure();
 
-  /** creates the common disclainer text at the top of each makefile */
-  void WriteDisclaimer(std::ostream& os);
+  /**
+   * Generate the makefile for this directory. 
+   */
+  virtual void Generate();
 
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
   // this returns the relative path between the HomeOutputDirectory and this
   // local generators StartOutputDirectory
   const std::string &GetHomeRelativeOutputPath();
@@ -66,9 +77,6 @@ public:
   // write the main variables used by the makefiles
   void WriteMakeVariables(std::ostream& makefileStream);
 
-  // write a  comment line #====... in the stream
-  void WriteDivider(std::ostream& os);
-
   /**
    * If true, then explicitly pass MAKEFLAGS on the make all target for makes
    * that do not use environment variables.
@@ -83,10 +91,6 @@ public:
   void SetMakeSilentFlag(const char* s) { m_MakeSilentFlag = s; }
   std::string &GetMakeSilentFlag() { return m_MakeSilentFlag; }
 
-  /** used to create a recursive make call */
-  std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);  
-  
-  
   /** Set whether the echo command needs its argument quoted.  */
   void SetEchoNeedsQuote(bool b) { m_EchoNeedsQuote = b; }
 
@@ -134,8 +138,39 @@ public:
    */
   void SetIgnoreLibPrefix(bool s) { m_IgnoreLibPrefix = s; }
 
-    
+  // used in writing out Cmake files such as WriteDirectoryInformation
+  static void WriteCMakeArgument(std::ostream& os, const char* s);
+
+  /** creates the common disclainer text at the top of each makefile */
+  void WriteDisclaimer(std::ostream& os);
+
+  // write a  comment line #====... in the stream
+  void WriteDivider(std::ostream& os);
+
+  /** used to create a recursive make call */
+  std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);    
   
+  // append an echo command
+  void AppendEcho(std::vector<std::string>& commands, const char* text);
+
+  static std::string GetTargetDirectory(cmTarget& target);
+
+    // create a command that cds to the start dir then runs the commands
+  void CreateCDCommand(std::vector<std::string>& commands, 
+                       const char *targetDir, const char *returnDir);
+
+  static std::string ConvertToQuotedOutputPath(const char* p);
+
+  std::string& CreateSafeUniqueObjectFileName(const char* sin);
+  std::string CreateMakeVariable(const char* sin, const char* s2in);
+
+  // cleanup the name of a potential target
+  std::string ConvertToMakeTarget(const char* tgt);
+
+
+  const char* GetSourceFileLanguage(const cmSourceFile& source);
+
+
   
   
   /** Called from command-line hook to scan dependencies.  */
@@ -145,10 +180,10 @@ public:
   virtual void CheckDependencies(cmMakefile* mf, bool verbose,
                                  bool clear);
   
-  /** write some extra rules suahc as make test etc */
+  /** write some extra rules such as make test etc */
   void WriteSpecialTargetsTop(std::ostream& makefileStream);
-
   void WriteSpecialTargetsBottom(std::ostream& makefileStream);
+
   std::string GetRelativeTargetDirectory(cmTarget& target);
 
   // List the files for which to check dependency integrity.  Each
@@ -159,140 +194,59 @@ public:
   std::map<cmStdString, IntegrityCheckSetMap> &GetIntegrityCheckSet() 
   { return m_CheckDependFiles;}
   
-  void AppendTargetDepends(std::vector<std::string>& depends,
-                           cmTarget& target);
-
   void AppendGlobalTargetDepends(std::vector<std::string>& depends,
                                  cmTarget& target);
 
-  void AppendEcho(std::vector<std::string>& commands,
-                  const char* text);
-
   // write the target rules for the local Makefile into the stream
   void WriteLocalAllRules(std::ostream& ruleFileStream);
   
   std::map<cmStdString,std::vector<cmTarget *> > GetLocalObjectFiles()
     { return m_LocalObjectFiles;}
+
 protected:
-  // Return the a string with -F flags on apple
-  std::string GetFrameworkFlags(cmTarget&);
-  
-  // write the depend info 
-  void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
+  // these two methods just compute reasonable values for m_LibraryOutputPath
+  // and m_ExecutableOutputPath
+  void ConfigureOutputPaths();
+  void FormatOutputPath(std::string& path, const char* name);
+
+  void WriteLocalMakefile();
   
   // write the target rules for the local Makefile into the stream
   void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
                                  std::set<cmStdString> &emitted);
 
-  // write the local help rule
-  void WriteHelpRule(std::ostream& ruleFileStream);
+  // this method Writes the Directory informaiton files
+  void WriteDirectoryInformationFile();
+
+
   
-  // create a command that cds to the start dir then runs the commands
-  void CreateCDCommand(std::vector<std::string>& commands, 
-                       const char *targetDir, const char *returnDir);
 
-  // these two methods just compute reasonable values for m_LibraryOutputPath
-  // and m_ExecutableOutputPath
-  void ConfigureOutputPaths();
-  void FormatOutputPath(std::string& path, const char* name);
 
-  // this converts a file name that is relative to the StartOuputDirectory
-  // into a full path
-  std::string ConvertToFullPath(const std::string& localPath);
 
-  // this is responsible for writing all of the rules for all this
-  // directories custom commands (but not utility targets)
-  void WriteCustomCommands(std::ostream& os,
-                           std::vector<std::string>& cleanFiles);
-  
-  // this method Writes the Directory informaiton files
-  void WriteDirectoryInformationFile();
 
-  // cleanup the name of a potential target
-  std::string ConvertToMakeTarget(const char* tgt);
 
-  // used in writing out Cmake files such as WriteDirectoryInformation
-  void WriteCMakeArgument(std::ostream& os, const char* s);
 
-  // write out all the rules for this target
-  void WriteTargetRuleFiles(cmTarget& target);
-  void WriteUtilityRuleFiles(cmTarget& target);
-  
-  // create the rule files for an object
-  void WriteObjectRuleFiles(cmTarget& target,
-                            cmSourceFile& source,
-                            std::vector<std::string>& objects,
-                            std::ostream &filestr,
-                            std::ostream &flagstr);
-
-  // write the build rule for an object
-  void WriteObjectBuildFile(std::string &obj,
-                            const char *lang, 
-                            cmTarget& target, 
-                            cmSourceFile& source,
-                            std::vector<std::string>& depends,
-                            std::ostream &filestr,
-                            std::ostream &flagstr);
-  
-  // write the depend.make file for an object
-  void WriteObjectDependRules(cmSourceFile& source,
-                              std::vector<std::string>& depends);
-  
-  void GenerateCustomRuleFile(const cmCustomCommand& cc, 
-                              std::ostream &ruleStream);
-  
-  // these three make some simple changes and then call WriteLibraryRule
-  void WriteStaticLibraryRule(std::ostream& ruleFileStream,
-                              const char* ruleFileName,
-                              cmTarget& target,
-                              const std::vector<std::string>& objects,
-                              const std::vector<std::string>& external_objects,
-                              std::vector<std::string>& cleanFiles);
-  
-  void WriteSharedLibraryRule(std::ostream& ruleFileStream,
-                              const char* ruleFileName,
-                              cmTarget& target,
-                              const std::vector<std::string>& objects,
-                              const std::vector<std::string>& external_objects,
-                              std::vector<std::string>& cleanFiles);
-  
-  void WriteModuleLibraryRule(std::ostream& ruleFileStream,
-                              const char* ruleFileName,
-                              cmTarget& target,
-                              const std::vector<std::string>& objects,
-                              const std::vector<std::string>& external_objects,
-                              std::vector<std::string>& cleanFiles);
-
-  // the main code for writing the Executable target rules
-  void WriteExecutableRule(std::ostream& ruleFileStream,
-                           const char* ruleFileName,
-                           cmTarget& target,
-                           const std::vector<std::string>& objects,
-                           const std::vector<std::string>& external_objects,
-                           std::vector<std::string>& cleanFiles);
-
-  // the main method for writing library rules
-  void WriteLibraryRule(std::ostream& ruleFileStream,
-                        const char* ruleFileName,
-                        cmTarget& target,
-                        const std::vector<std::string>& objects,
-                        const std::vector<std::string>& external_objects,
-                        const char* linkRuleVar,
-                        const char* extraLinkFlags,
-                        std::vector<std::string>& cleanFiles);
+
+
+
+
+
+
+  // write the depend info 
+  void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
   
-  void WriteLocalMakefile();
+  // write the local help rule
+  void WriteHelpRule(std::ostream& ruleFileStream);
   
+  // this converts a file name that is relative to the StartOuputDirectory
+  // into a full path
+  std::string ConvertToFullPath(const std::string& localPath);
+
   
   void WriteConvenienceRule(std::ostream& ruleFileStream,
                             const char* realTarget,
                             const char* helpTarget);
-  void WriteObjectsVariable(std::ostream& ruleFileStream,
-                            cmTarget& target,
-                            const std::vector<std::string>& objects,
-                            const std::vector<std::string>& external_objects,
-                            std::string& variableName,
-                            std::string& variableNameExternal);
+
   void WriteTargetDependRule(std::ostream& ruleFileStream,
                              cmTarget& target);
   void WriteTargetCleanRule(std::ostream& ruleFileStream,
@@ -302,12 +256,9 @@ protected:
                                cmTarget& target,
                                const std::vector<std::string>& objects);
   
-  std::string GetTargetDirectory(cmTarget& target);
   std::string GetObjectFileName(cmTarget& target,
                                 const cmSourceFile& source,
                                 std::string* nameWithoutTargetDir = 0);
-  const char* GetSourceFileLanguage(const cmSourceFile& source);
-  std::string ConvertToQuotedOutputPath(const char* p);
 
   void AppendRuleDepend(std::vector<std::string>& depends,
                         const char* ruleFileName);
@@ -322,20 +273,17 @@ protected:
   void AppendCleanCommand(std::vector<std::string>& commands,
                           const std::vector<std::string>& files);
 
-  //==========================================================================
-  std::string& CreateSafeUniqueObjectFileName(const char* sin);
-  std::string CreateMakeVariable(const char* sin, const char* s2in);
-  //==========================================================================
-
 private:
+  friend class cmMakefileTargetGenerator;
+  friend class cmMakefileExecutableTargetGenerator;
+  friend class cmMakefileLibraryTargetGenerator;
+  friend class cmMakefileUtilityTargetGenerator;
+  
   std::map<cmStdString, IntegrityCheckSetMap> m_CheckDependFiles;
 
   //==========================================================================
   // Configuration settings.
   int m_MakefileVariableSize;
-  std::map<cmStdString, cmStdString> m_MakeVariableMap;
-  std::map<cmStdString, cmStdString> m_ShortMakeVariableMap;
-  std::map<cmStdString, cmStdString> m_UniqueObjectNamesMap;
   std::string m_IncludeDirective;
   std::string m_MakeSilentFlag;
   std::string m_ExecutableOutputPath;
@@ -345,17 +293,19 @@ private:
   bool m_UnixCD;
   bool m_PassMakeflags;
   bool m_SilentNoColon;
-  //==========================================================================
-
   // Flag for whether echo command needs quotes.
   bool m_EchoNeedsQuote;
+  //==========================================================================
 
   std::string m_HomeRelativeOutputPath;
   
-  // Set of object file names that will be built in this directory.
-  std::set<cmStdString> m_ObjectFiles;
-
   std::map<cmStdString,std::vector<cmTarget *> > m_LocalObjectFiles;
+
+  /* does the work for each target */
+  std::vector<cmMakefileTargetGenerator *> TargetGenerators;
+  std::map<cmStdString, cmStdString> m_MakeVariableMap;
+  std::map<cmStdString, cmStdString> m_ShortMakeVariableMap;
+  std::map<cmStdString, cmStdString> m_UniqueObjectNamesMap;
 };
 
 #endif
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index eaf8f86..143cd7c 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -144,7 +144,7 @@ protected:
     return this->LocalGenerator->Convert(source, relative, output, optional);
   }
 
-  // constructor to set the ivarscmMakefileTargetGenerator
+  // constructor to set the ivars
   cmMakefileTargetGenerator();
 
 };
diff --git a/bootstrap b/bootstrap
index e76bbaa..30466cc 100755
--- a/bootstrap
+++ b/bootstrap
@@ -83,6 +83,10 @@ CMAKE_CXX_SOURCES="\
   cmXCodeObject \
   cmXCode21Object \
   cmLocalUnixMakefileGenerator3 \
+  cmMakefileExecutableTargetGenerator \
+  cmMakefileLibraryTargetGenerator \
+  cmMakefileTargetGenerator \
+  cmMakefileUtilityTargetGenerator \
   cmBootstrapCommands \
   cmCommands \
   cmTarget \
-- 
cgit v0.12