From 7740ccd1a41e837b89cd5bb7b87d9654b7b745a2 Mon Sep 17 00:00:00 2001
From: Ken Martin <ken.martin@kitware.com>
Date: Tue, 14 Feb 2006 10:36:04 -0500
Subject: [PATCH] ENH: some cleanup of the makefile generator

---
 .../cmMakefileExecutableTargetGenerator.cxx   | 334 ++++++++
 Source/cmMakefileExecutableTargetGenerator.h  |  34 +
 Source/cmMakefileLibraryTargetGenerator.cxx   | 394 +++++++++
 Source/cmMakefileLibraryTargetGenerator.h     |  37 +
 Source/cmMakefileTargetGenerator.cxx          | 794 ++++++++++++++++++
 Source/cmMakefileTargetGenerator.h            | 152 ++++
 Source/cmMakefileUtilityTargetGenerator.cxx   |  90 ++
 Source/cmMakefileUtilityTargetGenerator.h     |  34 +
 8 files changed, 1869 insertions(+)
 create mode 100644 Source/cmMakefileExecutableTargetGenerator.cxx
 create mode 100644 Source/cmMakefileExecutableTargetGenerator.h
 create mode 100644 Source/cmMakefileLibraryTargetGenerator.cxx
 create mode 100644 Source/cmMakefileLibraryTargetGenerator.h
 create mode 100644 Source/cmMakefileTargetGenerator.cxx
 create mode 100644 Source/cmMakefileTargetGenerator.h
 create mode 100644 Source/cmMakefileUtilityTargetGenerator.cxx
 create mode 100644 Source/cmMakefileUtilityTargetGenerator.h

diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
new file mode 100644
index 0000000000..03acb8c446
--- /dev/null
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -0,0 +1,334 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmMakefileExecutableTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+//----------------------------------------------------------------------------
+void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
+{
+  // create the build.make file and directory, put in the common blocks
+  this->CreateRuleFile();
+  
+  // Add in any rules for custom commands
+  this->WriteCustomCommandsForTarget();
+
+  // write in rules for object files
+  this->WriteCommonCodeRules();
+  
+  // write the link rules
+  this->WriteExecutableRule();
+
+  // Write the requires target.
+  this->WriteTargetRequiresRules();
+
+  // Write clean target
+  this->WriteTargetCleanRules();
+
+  // close the streams
+  this->CloseFileStreams();
+}
+
+
+
+//----------------------------------------------------------------------------
+void cmMakefileExecutableTargetGenerator::WriteExecutableRule()
+{
+  // Write the dependency generation rule.
+  this->WriteTargetDependRules();
+
+  std::vector<std::string> commands;
+
+  std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
+  std::string objTarget;
+
+  // Build list of dependencies.
+  std::vector<std::string> depends;
+  for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
+      obj != this->Objects.end(); ++obj)
+    {
+    objTarget = relPath;
+    objTarget += *obj;
+    depends.push_back(objTarget);
+    }
+
+  // Add dependencies on targets that must be built first.
+  this->AppendTargetDepends(depends);
+
+  // Add a dependency on the rule file itself.
+  this->LocalGenerator->AppendRuleDepend(depends,
+                                         this->BuildFileNameFull.c_str());
+  
+  for(std::vector<std::string>::const_iterator obj = 
+        this->ExternalObjects.begin();
+      obj != this->ExternalObjects.end(); ++obj)
+    {
+    depends.push_back(*obj);
+    }
+
+  // from here up is the same for exe or lib
+
+  // Get the name of the executable to generate.
+  std::string targetName;
+  std::string targetNameReal;
+  this->Target->GetExecutableNames(targetName, targetNameReal,
+                                   this->LocalGenerator->m_ConfigurationName.c_str());
+
+  // Construct the full path version of the names.
+  std::string outpath = this->LocalGenerator->m_ExecutableOutputPath;
+  if(outpath.length() == 0)
+    {
+    outpath = this->Makefile->GetStartOutputDirectory();
+    outpath += "/";
+    }
+#ifdef __APPLE__
+  if(this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
+    {
+    // Make bundle directories
+    outpath += this->Target->GetName();
+    outpath += ".app/Contents/MacOS/";
+    std::string f1 = 
+      this->Makefile->GetModulesFile("MacOSXBundleInfo.plist.in");
+    if ( f1.size() == 0 )
+      {
+      cmSystemTools::Error("could not find Mac OSX bundle template file.");
+      }
+    std::string macdir = 
+      this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+    if ( macdir.size() == 0 )
+      {
+      macdir = this->Makefile->GetCurrentOutputDirectory();
+      }
+    if(macdir.size() && macdir[macdir.size()-1] != '/')
+      {
+      macdir += "/";
+      }
+    macdir += this->Target->GetName();
+    macdir += ".app/Contents/";
+    std::string f2 = macdir + "Info.plist";
+    macdir += "MacOS";
+    cmSystemTools::MakeDirectory(macdir.c_str());
+    this->Makefile->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", this->Target->GetName());
+    this->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(),
+                                  cmLocalGenerator::START_OUTPUT,
+                                  cmLocalGenerator::MAKEFILE);
+  std::string targetOutPathReal =
+    this->Convert(targetFullPathReal.c_str(),
+                                  cmLocalGenerator::START_OUTPUT,
+                                  cmLocalGenerator::MAKEFILE);
+
+  // Get the language to use for linking this executable.
+  const char* linkLanguage =
+    this->Target->GetLinkerLanguage(this->GlobalGenerator);
+
+  // Make sure we have a link language.
+  if(!linkLanguage)
+    {
+    cmSystemTools::Error("Cannot determine link language for target \"",
+                         this->Target->GetName(), "\".");
+    return;
+    }
+
+  // Add the link message.
+  std::string buildEcho = "Linking ";
+  buildEcho += linkLanguage;
+  buildEcho += " executable ";
+  buildEcho += targetOutPath;
+  this->LocalGenerator->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->LocalGenerator->AddSharedFlags(linkFlags, linkLanguage, true);
+
+  // Add flags to create an executable.
+  this->LocalGenerator->
+    AddConfigVariableFlags(linkFlags, "CMAKE_EXE_LINKER_FLAGS");
+
+
+  if(this->Target->GetPropertyAsBool("WIN32_EXECUTABLE"))
+    {
+    this->LocalGenerator->AppendFlags(linkFlags,
+                                      this->Makefile->GetDefinition("CMAKE_CREATE_WIN32_EXE"));
+    }
+  else
+    {
+    this->LocalGenerator->AppendFlags(linkFlags,
+                                      this->Makefile->GetDefinition("CMAKE_CREATE_CONSOLE_EXE"));
+    }
+
+  // Add language-specific flags.
+  this->LocalGenerator->AddLanguageFlags(flags, linkLanguage);
+
+  // Add target-specific linker flags.
+  this->LocalGenerator->AppendFlags(linkFlags, this->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;
+  this->Target->GetExecutableCleanNames(cleanName, cleanRealName,
+                                        this->LocalGenerator->m_ConfigurationName.c_str());
+  std::string cleanFullName = outpath + cleanName;
+  std::string cleanFullRealName = outpath + cleanRealName;
+  exeCleanFiles.push_back(this->Convert(cleanFullName.c_str(),
+                                        cmLocalGenerator::START_OUTPUT,
+                                        cmLocalGenerator::MAKEFILE));
+  if(cleanRealName != cleanName)
+    {
+    exeCleanFiles.push_back(this->Convert(cleanFullRealName.c_str(),
+                                          cmLocalGenerator::START_OUTPUT,
+                                          cmLocalGenerator::MAKEFILE));
+    }
+  } 
+
+  // Add a command to remove any existing files for this executable.
+  std::vector<std::string> commands1;
+  this->LocalGenerator->AppendCleanCommand(commands1, exeCleanFiles);
+  this->LocalGenerator->CreateCDCommand(commands1,
+                                        this->Makefile->GetStartOutputDirectory(),
+                                        this->Makefile->GetHomeOutputDirectory()); 
+  commands.insert(commands.end(), commands1.begin(), commands1.end());
+  commands1.clear();
+  // Add the pre-build and pre-link rules.
+  this->LocalGenerator->
+    AppendCustomCommands(commands, this->Target->GetPreBuildCommands());
+  this->LocalGenerator->
+    AppendCustomCommands(commands, this->Target->GetPreLinkCommands());
+
+  // Construct the main link rule.
+  std::string linkRuleVar = "CMAKE_";
+  linkRuleVar += linkLanguage;
+  linkRuleVar += "_LINK_EXECUTABLE";
+  std::string linkRule = 
+    this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
+  cmSystemTools::ExpandListArgument(linkRule, commands1);
+  this->LocalGenerator->CreateCDCommand
+    (commands1,
+     this->Makefile->GetStartOutputDirectory(),
+     this->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->LocalGenerator->AppendCustomCommands
+    (commands, this->Target->GetPostBuildCommands());
+
+  // Collect up flags to link in needed libraries.
+  cmOStringStream linklibs;
+  this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target);
+
+  // Construct object file lists that may be needed to expand the
+  // rule.
+  std::string variableName;
+  std::string variableNameExternal;
+  this->WriteObjectsVariable(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->LocalGenerator->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->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 
+                                      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->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                        targetFullPath.c_str(), 
+                                        depends, commands);
+    }
+
+  // Write convenience targets.
+  std::string dir = this->Makefile->GetStartOutputDirectory();
+  dir += "/";
+  dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
+  std::string buildTargetRuleName = dir;
+  buildTargetRuleName += "/build";
+  buildTargetRuleName = 
+    this->Convert(buildTargetRuleName.c_str(),
+                  cmLocalGenerator::HOME_OUTPUT,
+                  cmLocalGenerator::MAKEFILE);
+  this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream, 
+                                             targetFullPath.c_str(),
+                                             buildTargetRuleName.c_str());
+
+  // Clean all the possible executable names and symlinks and object files.
+  this->CleanFiles.insert(this->CleanFiles.end(),
+                          exeCleanFiles.begin(),
+                          exeCleanFiles.end());
+  this->CleanFiles.push_back(cleanObjs);
+}
+
diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h
new file mode 100644
index 0000000000..a02286c361
--- /dev/null
+++ b/Source/cmMakefileExecutableTargetGenerator.h
@@ -0,0 +1,34 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmMakefileExecutableTargetGenerator_h
+#define cmMakefileExecutableTargetGenerator_h
+
+#include "cmMakefileTargetGenerator.h"
+
+class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
+{
+public:
+  /* the main entry point for this class. Writes the Makefiles associated
+     with this target */
+  virtual void WriteRuleFiles();
+  
+protected:
+  virtual void WriteExecutableRule();
+  
+};
+
+#endif
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
new file mode 100644
index 0000000000..89057f658f
--- /dev/null
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -0,0 +1,394 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmMakefileLibraryTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
+{
+  // create the build.make file and directory, put in the common blocks
+  this->CreateRuleFile();
+  
+  // Add in any rules for custom commands
+  this->WriteCustomCommandsForTarget();
+
+  // write in rules for object files
+  this->WriteCommonCodeRules();
+  
+  // write the link rules
+  // Write the rule for this target type.
+  switch(this->Target->GetType())
+    {
+    case cmTarget::STATIC_LIBRARY:
+      this->WriteStaticLibraryRules();
+      break;
+    case cmTarget::SHARED_LIBRARY:
+      this->WriteSharedLibraryRules();
+      break;
+    case cmTarget::MODULE_LIBRARY:
+      this->WriteModuleLibraryRules();
+      break;
+    default:
+      // If language is not known, this is an error.
+      cmSystemTools::Error("Unknown Library Type");
+      break;
+    }
+
+  // Write the requires target.
+  this->WriteTargetRequiresRules();
+
+  // Write clean target
+  this->WriteTargetCleanRules();
+
+  // close the streams
+  this->CloseFileStreams();
+}
+
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
+{
+  const char* linkLanguage =
+    this->Target->GetLinkerLanguage(this->GlobalGenerator);
+  std::string linkRuleVar = "CMAKE_";
+  if (linkLanguage)
+    {
+    linkRuleVar += linkLanguage;
+    }
+  linkRuleVar += "_CREATE_STATIC_LIBRARY";
+
+  std::string extraFlags;
+  this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("STATIC_LIBRARY_FLAGS"));
+  this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules()
+{
+  const char* linkLanguage =
+    this->Target->GetLinkerLanguage(this->GlobalGenerator);
+  std::string linkRuleVar = "CMAKE_";
+  if (linkLanguage)
+    {
+    linkRuleVar += linkLanguage;
+    }
+  linkRuleVar += "_CREATE_SHARED_LIBRARY";
+
+  std::string extraFlags;
+  this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS"));
+  this->LocalGenerator->AddConfigVariableFlags(extraFlags, "CMAKE_SHARED_LINKER_FLAGS");
+  if(this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW")))
+    {
+    const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
+    for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
+        i != sources.end(); ++i)
+      {
+      if((*i)->GetSourceExtension() == "def")
+        {
+        extraFlags += " ";
+        extraFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+        extraFlags += 
+          this->Convert((*i)->GetFullPath().c_str(),cmLocalGenerator::START_OUTPUT,cmLocalGenerator::MAKEFILE);
+        }
+      }
+    }
+  this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules()
+{
+  const char* linkLanguage =
+    this->Target->GetLinkerLanguage(this->GlobalGenerator);
+  std::string linkRuleVar = "CMAKE_";
+  if (linkLanguage)
+    {
+    linkRuleVar += linkLanguage;
+    }
+  linkRuleVar += "_CREATE_SHARED_MODULE";
+
+  std::string extraFlags;
+  this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS"));
+  this->LocalGenerator->AddConfigVariableFlags(extraFlags, "CMAKE_MODULE_LINKER_FLAGS");
+  // TODO: .def files should be supported here also.
+  this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteLibraryRules
+(const char* linkRuleVar, const char* extraFlags)
+{
+  // Write the dependency generation rule.
+  this->WriteTargetDependRules();
+
+  // TODO: Merge the methods that call this method to avoid
+  // code duplication.
+  std::vector<std::string> commands;
+
+  std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
+  std::string objTarget;
+
+  // Build list of dependencies.
+  std::vector<std::string> depends;
+  for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
+      obj != this->Objects.end(); ++obj)
+    {
+    objTarget = relPath;
+    objTarget += *obj;
+    depends.push_back(objTarget);
+    }
+
+  // Add dependencies on targets that must be built first.
+  this->AppendTargetDepends(depends);
+
+  // Add a dependency on the rule file itself.
+  this->LocalGenerator->AppendRuleDepend(depends, 
+                                         this->BuildFileNameFull.c_str());
+  
+  for(std::vector<std::string>::const_iterator obj 
+        = this->ExternalObjects.begin();
+      obj != this->ExternalObjects.end(); ++obj)
+    {
+    depends.push_back(*obj);
+    }
+  
+  // Get the language to use for linking this library.
+  const char* linkLanguage =
+    this->Target->GetLinkerLanguage(this->GlobalGenerator);
+
+  // Make sure we have a link language.
+  if(!linkLanguage)
+    {
+    cmSystemTools::Error("Cannot determine link language for target \"",
+                         this->Target->GetName(), "\".");
+    return;
+    }
+
+  // Create set of linking flags.
+  std::string linkFlags;
+  this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
+
+  // Construct the name of the library.
+  std::string targetName;
+  std::string targetNameSO;
+  std::string targetNameReal;
+  this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+                                this->LocalGenerator->m_ConfigurationName.c_str());
+
+  // Construct the full path version of the names.
+  std::string outpath = this->LocalGenerator->m_LibraryOutputPath;
+  if(outpath.length() == 0)
+    {
+    outpath = this->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(),cmLocalGenerator::START_OUTPUT,
+                  cmLocalGenerator::MAKEFILE);
+  std::string targetOutPathSO = 
+    this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT,
+                  cmLocalGenerator::MAKEFILE);
+  std::string targetOutPathReal = 
+    this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT,
+                  cmLocalGenerator::MAKEFILE);
+
+  // Add the link message.
+  std::string buildEcho = "Linking ";
+  buildEcho += linkLanguage;
+  switch(this->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->LocalGenerator->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;
+  this->Target->GetLibraryCleanNames(cleanStaticName,
+                              cleanSharedName,
+                              cleanSharedSOName,
+                              cleanSharedRealName,
+                              this->LocalGenerator->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(),cmLocalGenerator::START_OUTPUT,
+                   cmLocalGenerator::MAKEFILE));
+  if(cleanSharedRealName != cleanStaticName)
+    {
+    libCleanFiles.push_back(this->Convert(cleanFullSharedRealName.c_str(),
+                                          cmLocalGenerator::START_OUTPUT,
+                                          cmLocalGenerator::MAKEFILE));
+    }
+  if(cleanSharedSOName != cleanStaticName &&
+     cleanSharedSOName != cleanSharedRealName)
+    {
+    libCleanFiles.push_back(this->Convert(cleanFullSharedSOName.c_str(),
+                                          cmLocalGenerator::START_OUTPUT,
+                                          cmLocalGenerator::MAKEFILE));
+    }
+  if(cleanSharedName != cleanStaticName &&
+     cleanSharedName != cleanSharedSOName &&
+     cleanSharedName != cleanSharedRealName)
+    {
+    libCleanFiles.push_back(this->Convert(cleanFullSharedName.c_str(),
+                                          cmLocalGenerator::START_OUTPUT,
+                                          cmLocalGenerator::MAKEFILE));
+    }
+  }
+  // Add a command to remove any existing files for this library.
+  std::vector<std::string> commands1;
+  this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles);
+  this->LocalGenerator->CreateCDCommand(commands1,
+                                        this->Makefile->GetStartOutputDirectory(),
+                                        this->Makefile->GetHomeOutputDirectory());
+  commands.insert(commands.end(), commands1.begin(), commands1.end());
+  commands1.clear();
+  // Add the pre-build and pre-link rules.
+  this->LocalGenerator->AppendCustomCommands(commands, this->Target->GetPreBuildCommands());
+  this->LocalGenerator->AppendCustomCommands(commands, this->Target->GetPreLinkCommands());
+
+  // Construct the main link rule.
+  std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
+  cmSystemTools::ExpandListArgument(linkRule, commands1);
+  this->LocalGenerator->CreateCDCommand(commands1,
+                                        this->Makefile->GetStartOutputDirectory(),
+                                        this->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->LocalGenerator->CreateCDCommand(commands1,
+                                  this->Makefile->GetStartOutputDirectory(),
+                                  this->Makefile->GetHomeOutputDirectory());
+    commands.insert(commands.end(), commands1.begin(), commands1.end());
+    }
+
+  // Add the post-build rules.
+  this->LocalGenerator->AppendCustomCommands(commands, this->Target->GetPostBuildCommands());
+
+  // Collect up flags to link in needed libraries.
+  cmOStringStream linklibs;
+  this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target);
+
+  // Construct object file lists that may be needed to expand the
+  // rule.
+  std::string variableName;
+  std::string variableNameExternal;
+  this->WriteObjectsVariable(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->LocalGenerator->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->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 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->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                        targetFullPathSO.c_str(), depends, commands);
+    }
+  if(targetFullPath != targetFullPathSO)
+    {
+    depends.clear();
+    commands.clear();
+    depends.push_back(targetFullPathSO.c_str());
+    this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                        targetFullPath.c_str(), depends, commands);
+    }
+
+  // Write convenience targets.
+  std::string dir = this->Makefile->GetStartOutputDirectory();
+  dir += "/";
+  dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
+  std::string buildTargetRuleName = dir;
+  buildTargetRuleName += "/build";
+  buildTargetRuleName = 
+    this->Convert(buildTargetRuleName.c_str(),
+                  cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
+  this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream, 
+                                             targetFullPath.c_str(),
+                                             buildTargetRuleName.c_str());
+
+  // Clean all the possible library names and symlinks and object files.
+  this->CleanFiles.insert(this->CleanFiles.end(),
+                          libCleanFiles.begin(),libCleanFiles.end());
+  this->CleanFiles.push_back(cleanObjs);
+}
+
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
new file mode 100644
index 0000000000..7c7c43d41c
--- /dev/null
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -0,0 +1,37 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmMakefileLibraryTargetGenerator_h
+#define cmMakefileLibraryTargetGenerator_h
+
+#include "cmMakefileTargetGenerator.h"
+
+class cmMakefileLibraryTargetGenerator: 
+  public cmMakefileTargetGenerator
+{
+public:
+  /* the main entry point for this class. Writes the Makefiles associated
+     with this target */
+  virtual void WriteRuleFiles();  
+  
+protected:
+  void WriteStaticLibraryRules();
+  void WriteSharedLibraryRules();
+  void WriteModuleLibraryRules();
+  void WriteLibraryRules(const char *linkRule, const char *extraFlags);
+};
+
+#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
new file mode 100644
index 0000000000..87bef2861c
--- /dev/null
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -0,0 +1,794 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmMakefileTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+#include "cmMakefileExecutableTargetGenerator.h"
+#include "cmMakefileLibraryTargetGenerator.h"
+#include "cmMakefileUtilityTargetGenerator.h"
+
+
+cmMakefileTargetGenerator::cmMakefileTargetGenerator()
+{
+  this->BuildFileStream = 0;
+  this->InfoFileStream = 0;
+  this->FlagFileStream = 0;  
+}
+
+cmMakefileTargetGenerator *
+cmMakefileTargetGenerator::New(cmLocalUnixMakefileGenerator3 *lg,
+                               cmStdString tgtName, cmTarget *tgt)
+{
+  cmMakefileTargetGenerator *result = 0;
+
+  switch (tgt->GetType())
+    {
+    case cmTarget::EXECUTABLE:
+      result = new cmMakefileExecutableTargetGenerator;
+      break;
+    case cmTarget::STATIC_LIBRARY:
+    case cmTarget::SHARED_LIBRARY:
+    case cmTarget::MODULE_LIBRARY:
+      result = new cmMakefileLibraryTargetGenerator;
+      break;
+    case cmTarget::UTILITY:
+      result = new cmMakefileUtilityTargetGenerator;
+      break;
+    default:
+      return 0;
+      break;
+    }
+
+  result->TargetName = tgtName;
+  result->Target = tgt;
+  result->LocalGenerator = lg;
+  result->GlobalGenerator = lg->GetGlobalGenerator();
+  result->Makefile = lg->GetMakefile();
+  return result;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::CreateRuleFile()
+{
+  // Create a directory for this target.
+  this->TargetBuildDirectory = 
+    this->LocalGenerator->GetTargetDirectory(*this->Target);
+  this->TargetBuildDirectoryFull = 
+    this->LocalGenerator->ConvertToFullPath(this->TargetBuildDirectory);
+  cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull.c_str());
+  
+  // Construct the rule file name.
+  this->BuildFileName = this->TargetBuildDirectory;
+  this->BuildFileName += "/build.make";
+  this->BuildFileNameFull = this->TargetBuildDirectoryFull;
+  this->BuildFileNameFull += "/build.make";
+  
+  // Open the rule file.  This should be copy-if-different because the
+  // rules may depend on this file itself.
+  this->BuildFileStream = 
+    new cmGeneratedFileStream(this->BuildFileNameFull.c_str());
+  this->BuildFileStream->SetCopyIfDifferent(true);
+  if(!this->BuildFileStream)
+    {
+    return;
+    }
+  this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream);
+  this->LocalGenerator->WriteSpecialTargetsTop(*this->BuildFileStream);
+  this->LocalGenerator->WriteMakeVariables(*this->BuildFileStream);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteCustomCommandsForTarget()
+{
+  // write the custom commands for this target
+  // Look for files registered for cleaning in this directory.
+  if(const char* additional_clean_files =
+     this->Makefile->GetProperty
+     ("ADDITIONAL_MAKE_CLEAN_FILES"))
+    {
+    cmSystemTools::ExpandListArgument(additional_clean_files, 
+                                      this->CleanFiles);
+    }  
+  this->WriteCustomCommands();
+}
+
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteCommonCodeRules()
+{
+  // Include the dependencies for the target.
+  std::string dependFileNameFull = this->TargetBuildDirectoryFull;
+  dependFileNameFull += "/depend.make";
+  *this->BuildFileStream
+    << "# Include any dependencies generated for this target.\n"
+    << this->LocalGenerator->m_IncludeDirective << " "
+    << this->Convert(dependFileNameFull.c_str(),
+                                     cmLocalGenerator::HOME_OUTPUT,
+                                     cmLocalGenerator::MAKEFILE)
+    << "\n\n";
+  
+  // make sure the depend file exists
+  if (!cmSystemTools::FileExists(dependFileNameFull.c_str()))
+    {
+    // Write an empty dependency file.
+    cmGeneratedFileStream depFileStream(dependFileNameFull.c_str());
+    depFileStream
+      << "# Empty dependencies file for " << this->Target->GetName() << ".\n"
+      << "# This may be replaced when dependencies are built." << std::endl;
+    }
+
+  // Open the flags file.  This should be copy-if-different because the
+  // rules may depend on this file itself.
+  this->FlagFileNameFull = this->TargetBuildDirectoryFull;
+  this->FlagFileNameFull += "/flags.make";
+  this->FlagFileStream = 
+    new cmGeneratedFileStream(this->FlagFileNameFull.c_str());
+  this->FlagFileStream->SetCopyIfDifferent(true);
+  if(!this->FlagFileStream)
+    {
+    return;
+    }
+  this->LocalGenerator->WriteDisclaimer(*this->FlagFileStream);
+  
+  // Include the flags for the target.
+  *this->BuildFileStream
+    << "# Include the compile flags for this target's objects.\n"
+    << this->LocalGenerator->m_IncludeDirective << " "
+    << this->Convert(this->FlagFileNameFull.c_str(), 
+                                     cmLocalGenerator::HOME_OUTPUT, 
+                                     cmLocalGenerator::MAKEFILE)
+    << "\n\n";
+  
+  // First generate the object rule files.  Save a list of all object
+  // files for this target.
+  const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
+  for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
+      source != sources.end(); ++source)
+    {
+    if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
+       !(*source)->GetCustomCommand())
+      {
+      if(!this->GlobalGenerator->IgnoreFile
+         ((*source)->GetSourceExtension().c_str()))
+        {
+        // Generate this object file's rule file.
+        this->WriteObjectRuleFiles(*(*source));
+        }
+      else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
+        {
+        // This is an external object file.  Just add it.
+        this->ExternalObjects.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.
+        }
+      }
+    }
+  
+  // write language flags for target
+  std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& 
+    checkSet = 
+    this->LocalGenerator->GetIntegrityCheckSet()[this->Target->GetName()];
+  for(std::map<cmStdString, 
+        cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
+        l = checkSet.begin(); l != checkSet.end(); ++l)
+    {
+    const char *lang = l->first.c_str();
+    std::string flags;
+    // Add the export symbol definition for shared library objects.
+    bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) ||
+                   (this->Target->GetType() == cmTarget::MODULE_LIBRARY));
+    if(shared)
+      {
+      flags += "-D";
+      if(const char* custom_export_name = 
+         this->Target->GetProperty("DEFINE_SYMBOL"))
+        {
+        flags += custom_export_name;
+        }
+      else
+        {
+        std::string in = this->Target->GetName();
+        in += "_EXPORTS";
+        flags += cmSystemTools::MakeCindentifier(in.c_str());
+        }
+      }
+    
+    // Add language-specific flags.
+    this->LocalGenerator->AddLanguageFlags(flags, lang);
+    
+    // Add shared-library flags if needed.
+    this->LocalGenerator->AddSharedFlags(flags, lang, shared);
+    
+    // Add include directory flags.
+    this->LocalGenerator->
+      AppendFlags(flags, this->LocalGenerator->GetIncludeFlags(lang));
+    // Add include directory flags.
+    this->LocalGenerator->
+      AppendFlags(flags,this->GetFrameworkFlags().c_str());
+
+    *this->FlagFileStream << lang << "_FLAGS = " << flags << "\n\n";
+    }
+}
+
+
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
+{
+  // Identify the language of the source file.
+  const char* lang = this->LocalGenerator->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->LocalGenerator->GetObjectFileName(*this->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 \"" 
+        << this->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->LocalGenerator->ConvertToFullPath(dir).c_str());
+  
+  // Save this in the target's list of object files.
+  this->Objects.push_back(obj);
+  std::string relativeObj = this->LocalGenerator->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, source, depends);
+  
+  // The object file should be checked for dependency integrity.
+  this->LocalGenerator->m_CheckDependFiles[this->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);
+    }
+  this->LocalGenerator->m_LocalObjectFiles[objNoTargetDir].push_back(this->Target);
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::WriteObjectBuildFile(std::string &obj,
+                       const char *lang, 
+                       cmSourceFile& source,
+                       std::vector<std::string>& depends)
+{
+  this->LocalGenerator->AppendRuleDepend(depends, this->FlagFileNameFull.c_str());
+
+  // generate the depend scanning rule
+  this->WriteObjectDependRules(source, depends);
+
+  std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath();
+  relativeObj += obj;
+  if(this->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(this->Target->GetProperty("COMPILE_FLAGS"))
+    {
+    this->LocalGenerator->AppendFlags(flags, this->Target->GetProperty("COMPILE_FLAGS"));
+    }
+
+  // Add flags from source file properties.
+  if (source.GetProperty("COMPILE_FLAGS"))
+    {
+    this->LocalGenerator->AppendFlags(flags, source.GetProperty("COMPILE_FLAGS"));
+    *this->FlagFileStream << "# Custom flags: "
+                          << relativeObj << "_FLAGS = "
+                          << source.GetProperty("COMPILE_FLAGS")
+                          << "\n"
+                          << "\n";
+    }
+  
+  // Add language-specific flags.
+  std::string langFlags = "$(";
+  langFlags += lang;
+  langFlags += "_FLAGS)";
+  this->LocalGenerator->AppendFlags(flags, langFlags.c_str());
+  
+  // Get the output paths for source and object files.
+  std::string sourceFile = source.GetFullPath();
+  if(this->LocalGenerator->m_UseRelativePaths)
+    {
+    sourceFile = this->Convert(sourceFile.c_str(),
+                                               cmLocalGenerator::HOME_OUTPUT);
+    }
+  sourceFile = this->Convert(sourceFile.c_str(),
+                                             cmLocalGenerator::NONE,
+                                             cmLocalGenerator::SHELL);
+  std::string objectFile = 
+    this->Convert(obj.c_str(),
+                                  cmLocalGenerator::START_OUTPUT,
+                                  cmLocalGenerator::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->LocalGenerator->AppendEcho(commands, buildEcho.c_str());
+
+  // Construct the compile rules.
+  std::string compileRuleVar = "CMAKE_";
+  compileRuleVar += lang;
+  compileRuleVar += "_COMPILE_OBJECT";
+  std::string compileRule =
+    this->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->LocalGenerator->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->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+  depMark += "/depend.make.mark";
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                      depMark.c_str(), depends, no_commands);
+  
+  // Write the rule.
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 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->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 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->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+  tgtMakefileName += "/build.make";
+  r_commands.push_back
+    (this->LocalGenerator->GetRecursiveMakeCall(tgtMakefileName.c_str(),temp.c_str()));
+  p_depends.clear();
+  p_depends.push_back(objectRequires);
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 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->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                      temp.c_str(), p_depends, no_commands);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetRequiresRules()
+{
+  std::vector<std::string> depends;
+  std::vector<std::string> no_commands;
+
+  // Construct the name of the dependency generation target.
+  std::string depTarget = 
+    this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+  depTarget += "/requires";
+
+  // This target drives dependency generation for all object files.
+  std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
+  std::string objTarget;
+  for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
+      obj != this->Objects.end(); ++obj)
+    {
+    objTarget = relPath;
+    objTarget += *obj;
+    objTarget += ".requires";
+    depends.push_back(objTarget);
+    }
+
+  // Write the rule.
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                      depTarget.c_str(), depends, no_commands);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetCleanRules()
+{
+  std::vector<std::string> depends;
+  const char* sym = this->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->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+  cleanTarget += "/clean";
+  
+  // Construct the clean command.
+  this->LocalGenerator->AppendCleanCommand(commands, this->CleanFiles);
+  this->LocalGenerator->CreateCDCommand(commands,
+                                        this->Makefile->GetStartOutputDirectory(),
+                                        this->Makefile->GetHomeOutputDirectory());
+
+  // Write the rule.
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                      cleanTarget.c_str(), depends, commands);
+}
+
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetDependRules()
+{
+  // must write the targets depend info file
+  std::string dir = this->LocalGenerator->GetTargetDirectory(*this->Target);
+  this->InfoFileNameFull = dir;
+  this->InfoFileNameFull += "/DependInfo.cmake";
+  this->InfoFileNameFull = 
+    this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
+  this->InfoFileStream = 
+    new cmGeneratedFileStream(this->InfoFileNameFull.c_str());
+  this->InfoFileStream->SetCopyIfDifferent(true);
+  if(!*this->InfoFileStream)
+    {
+    return;
+    }
+  this->LocalGenerator->
+    WriteDependLanguageInfo(*this->InfoFileStream,*this->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->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+  depTarget += "/depend";
+  
+  std::string depMark = depTarget;
+  depMark += ".make.mark";
+  depends.push_back(depMark);
+  
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                      depTarget.c_str(), depends, commands);
+  depends.clear();
+  
+  // Write the dependency generation rule.
+  std::string depEcho = "Scanning dependencies of target ";
+  depEcho += this->Target->GetName();
+  this->LocalGenerator->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 " 
+         << " \""
+         << this->GlobalGenerator->GetName() << "\" "
+         << this->LocalGenerator->Convert
+    (this->Makefile->GetHomeOutputDirectory(),
+     cmLocalGenerator::FULL,cmLocalGenerator::SHELL)
+         << " "
+         << this->LocalGenerator->Convert
+    (this->Makefile->GetStartOutputDirectory(),
+     cmLocalGenerator::FULL,cmLocalGenerator::SHELL)
+         << " "
+         << this->Convert(this->InfoFileNameFull.c_str(),
+                          cmLocalGenerator::FULL,
+                          cmLocalGenerator::SHELL);
+  commands.push_back(depCmd.str());
+  
+  // Write the rule.
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                                      depMark.c_str(), depends, commands);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::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 cmMakefileTargetGenerator::WriteCustomCommands()
+{
+  // add custom commands to the clean rules?
+  const char* clean_no_custom = this->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 = this->Makefile->GetSourceFiles();
+  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); 
+      i != classes.end(); i++)
+    {
+    if(cmCustomCommand* cc = (*i)->GetCustomCommand())
+      {
+      this->GenerateCustomRuleFile(*cc);
+      if (clean)
+        {
+        this->CleanFiles.push_back
+          (this->Convert(cc->GetOutput(),
+                         cmLocalGenerator::START_OUTPUT,
+                         cmLocalGenerator::SHELL));
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::GenerateCustomRuleFile(const cmCustomCommand& cc)
+{
+  // Convert the output name to a relative path if possible.
+  std::string output = this->Convert(cc.GetOutput(),
+                                     cmLocalGenerator::START_OUTPUT);
+
+  // Collect the commands.
+  std::vector<std::string> commands;
+  std::string preEcho = "Generating ";
+  preEcho += output;
+  this->LocalGenerator->AppendEcho(commands, preEcho.c_str());
+  this->LocalGenerator->AppendCustomCommand(commands, cc);
+  
+  // Collect the dependencies.
+  std::vector<std::string> depends;
+  this->LocalGenerator->AppendCustomDepend(depends, cc);
+
+  // Write the rule.
+  const char* comment = 0;
+  if(cc.GetComment() && *cc.GetComment())
+    {
+    comment = cc.GetComment();
+    }
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment,
+                                      cc.GetOutput(), depends, commands);
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::WriteObjectsVariable(std::string& variableName,
+                       std::string& variableNameExternal)
+{
+  // Write a make variable assignment that lists all objects for the
+  // target.
+  variableName = 
+    this->LocalGenerator->CreateMakeVariable(this->Target->GetName(), "_OBJECTS");
+  *this->BuildFileStream
+    << "# Object files for target " << this->Target->GetName() << "\n"
+    << variableName.c_str() << " =";
+  std::string object;
+  const char* objName =  
+    this->Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS");
+  const char* lineContinue = 
+    this->Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE");
+  if(!lineContinue)
+    {
+    lineContinue = "\\";
+    }
+  for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+      i != this->Objects.end(); ++i)
+    {
+    *this->BuildFileStream << " " << lineContinue << "\n";
+    if(objName)
+      {
+      *this->BuildFileStream << 
+        this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT, 
+                      cmLocalGenerator::MAKEFILE);
+      }
+    else
+      {
+      *this->BuildFileStream  << 
+        this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
+      }
+    }
+  *this->BuildFileStream << "\n";
+
+  // Write a make variable assignment that lists all external objects
+  // for the target.
+  variableNameExternal = 
+    this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),"_EXTERNAL_OBJECTS");
+  *this->BuildFileStream
+    << "\n"
+    << "# External object files for target " << this->Target->GetName() << "\n"
+    << variableNameExternal.c_str() << " =";
+  for(std::vector<std::string>::const_iterator i = 
+        this->ExternalObjects.begin();
+      i != this->ExternalObjects.end(); ++i)
+    {
+    object = this->Convert(i->c_str(),cmLocalGenerator::START_OUTPUT);
+    *this->BuildFileStream
+      << " " << lineContinue << "\n"
+      << this->Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME");
+    if(objName)
+      {
+      *this->BuildFileStream  << this->Convert(i->c_str(), 
+                                               cmLocalGenerator::START_OUTPUT, 
+                                               cmLocalGenerator::MAKEFILE);
+      }
+    else
+      {
+      *this->BuildFileStream  << 
+        this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
+      }
+    }
+  *this->BuildFileStream << "\n" << "\n";
+}
+
+
+//----------------------------------------------------------------------------
+std::string cmMakefileTargetGenerator::GetFrameworkFlags()
+{
+#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()))
+      {
+      std::string frameworkDir = *i;
+      frameworkDir += "/../";
+      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
+      emitted.insert(frameworkDir);
+      }
+    }
+
+  std::string flags;
+  std::vector<std::string>& frameworks = this->Target->GetFrameworks();
+  for(i = frameworks.begin();
+      i != frameworks.end(); ++i)
+    {
+    if(emitted.insert(*i).second)
+      {
+      flags += "-F";
+      flags += this->LocalGenerator->ConvertToOutputForExisting(i->c_str());
+      flags += " ";
+      }
+    }
+  return flags;
+#endif
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::AppendTargetDepends(std::vector<std::string>& depends)
+{
+  // Static libraries never depend on anything for linking.
+  if(this->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(this->Target->GetName());
+
+  // Loop over all library dependencies.
+  const cmTarget::LinkLibraries& tlibs = this->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 = 
+         this->GlobalGenerator->FindTarget(0, lib->first.c_str()))
+        {
+        if(const char* location =
+           tgt->GetLocation(this->LocalGenerator->m_ConfigurationName.c_str()))
+          {
+          depends.push_back(location);
+          }
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::CloseFileStreams()
+{
+  delete this->BuildFileStream;
+  delete this->InfoFileStream;
+  delete this->FlagFileStream;
+}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
new file mode 100644
index 0000000000..eaf8f8693d
--- /dev/null
+++ b/Source/cmMakefileTargetGenerator.h
@@ -0,0 +1,152 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmMakefileTargetGenerator_h
+#define cmMakefileTargetGenerator_h
+
+#include "cmLocalUnixMakefileGenerator3.h"
+
+class cmCustomCommand;
+class cmDependInformation;
+class cmDepends;
+class cmGeneratedFileStream;
+class cmGlobalGenerator;
+class cmLocalUnixMakefileGenerator3;
+class cmMakeDepend;
+class cmMakefile;
+class cmTarget;
+class cmSourceFile;
+
+/** \class cmMakefileTargetGenerator
+ * \brief Support Routines for writing makefiles
+ *
+ */
+class cmMakefileTargetGenerator 
+{
+public:
+  // construct using this factory call
+  static cmMakefileTargetGenerator *New(cmLocalUnixMakefileGenerator3 *lg,
+                                        cmStdString tgtName,
+                                        cmTarget *tgt);
+
+  /* the main entry point for this class. Writes the Makefiles associated
+     with this target */
+  virtual void WriteRuleFiles() = 0;
+  
+protected:
+
+  // create the file and directory etc
+  void CreateRuleFile();
+  
+  // outputs the rules for any custom commands used by this target
+  void WriteCustomCommandsForTarget();
+
+  // write some common code at the top of build.make
+  void WriteCommonCodeRules();
+
+  // write the provide require rules for this target
+  void WriteTargetRequiresRules();
+
+  // write the clean rules for this target
+  void WriteTargetCleanRules();
+
+  // write the depend rules for this target
+  void WriteTargetDependRules();
+
+  // write the rules for an object
+  void WriteObjectRuleFiles(cmSourceFile& source);
+
+  // write the build rule for an object
+  void WriteObjectBuildFile(std::string &obj,
+                            const char *lang, 
+                            cmSourceFile& source,
+                            std::vector<std::string>& depends);
+  
+  // write the depend.make file for an object
+  void WriteObjectDependRules(cmSourceFile& source,
+                              std::vector<std::string>& depends);
+  
+  // this is responsible for writing all of the rules for all this
+  // directories custom commands (but not utility targets)
+  void WriteCustomCommands();
+  void GenerateCustomRuleFile(const cmCustomCommand& cc);
+  
+  // write out the variable that lists the objects for this target
+  void WriteObjectsVariable(std::string& variableName,
+                            std::string& variableNameExternal);
+  
+  // Return the a string with -F flags on apple
+  std::string GetFrameworkFlags();
+  
+  // append intertarget dependencies
+  void AppendTargetDepends(std::vector<std::string>& depends);
+
+  virtual void CloseFileStreams();
+  
+  cmStdString TargetName;
+  cmTarget *Target;
+  cmLocalUnixMakefileGenerator3 *LocalGenerator;
+  cmGlobalGenerator *GlobalGenerator;
+  cmMakefile *Makefile;
+  
+  // the full path to the build file
+  std::string BuildFileName;
+  std::string BuildFileNameFull;
+
+  // the path to the directory the build file is in
+  std::string TargetBuildDirectory;
+  std::string TargetBuildDirectoryFull;
+
+  // the stream for the build file
+  cmGeneratedFileStream *BuildFileStream;
+
+  // the stream for the flag file
+  std::string FlagFileNameFull;
+  cmGeneratedFileStream *FlagFileStream;
+
+  // the stream for the info file
+  std::string InfoFileNameFull;
+  cmGeneratedFileStream *InfoFileStream;
+
+  // files to clean
+  std::vector<std::string> CleanFiles;
+
+  // objects used by this target
+  std::vector<std::string> Objects;
+  std::vector<std::string> ExternalObjects;
+
+  // Set of object file names that will be built in this directory.
+  std::set<cmStdString> m_ObjectFiles;
+
+
+  //==================================================================
+  // Convenience routines that do nothing more than forward to 
+  // implementaitons
+  std::string Convert(const char* source, 
+                      cmLocalGenerator::RelativeRoot relative, 
+                      cmLocalGenerator::OutputFormat output = 
+                      cmLocalGenerator::UNCHANGED,
+                      bool optional = false) 
+  {
+    return this->LocalGenerator->Convert(source, relative, output, optional);
+  }
+
+  // constructor to set the ivarscmMakefileTargetGenerator
+  cmMakefileTargetGenerator();
+
+};
+
+#endif
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
new file mode 100644
index 0000000000..9843a0683c
--- /dev/null
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -0,0 +1,90 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmMakefileUtilityTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+
+//----------------------------------------------------------------------------
+void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
+{
+  this->CreateRuleFile();
+
+  *this->BuildFileStream
+    << "# Utility rule file for " << this->Target->GetName() << ".\n\n";
+
+  // write the custom commands for this target
+  this->WriteCustomCommandsForTarget();
+
+  // Collect the commands and dependencies.
+  std::vector<std::string> commands;
+  std::vector<std::string> depends;
+  const char* sym = this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE");
+  if(sym)
+    {
+    depends.push_back(sym);
+    }
+
+  // Utility targets store their rules in pre- and post-build commands.
+  this->LocalGenerator->AppendCustomDepends
+    (depends, this->Target->GetPreBuildCommands());
+  this->LocalGenerator->AppendCustomDepends
+    (depends, this->Target->GetPostBuildCommands());
+  this->LocalGenerator->AppendCustomCommands
+    (commands, this->Target->GetPreBuildCommands());
+  this->LocalGenerator->AppendCustomCommands
+    (commands, this->Target->GetPostBuildCommands());
+
+  // Add dependencies on targets that must be built first.
+  this->AppendTargetDepends(depends);
+  
+  // Add a dependency on the rule file itself.
+  std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
+  std::string objTarget = relPath;
+  objTarget += this->BuildFileName;
+  this->LocalGenerator->AppendRuleDepend(depends, objTarget.c_str());
+
+  // Write the rule.
+  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+                      this->Target->GetName(), depends, commands);
+
+  // Write convenience targets.
+  std::string dir = this->Makefile->GetStartOutputDirectory();
+  dir += "/";
+  dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
+  std::string buildTargetRuleName = dir;
+  buildTargetRuleName += "/build";
+  buildTargetRuleName = 
+    this->LocalGenerator->Convert(buildTargetRuleName.c_str(),
+                                  cmLocalGenerator::HOME_OUTPUT,
+                                  cmLocalGenerator::MAKEFILE);
+  this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream, 
+                                             this->Target->GetName(),
+                                             buildTargetRuleName.c_str());
+
+  // Write clean target
+  this->WriteTargetCleanRules();
+
+  // close the streams
+  this->CloseFileStreams();
+}
+
diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h
new file mode 100644
index 0000000000..c8642a6c68
--- /dev/null
+++ b/Source/cmMakefileUtilityTargetGenerator.h
@@ -0,0 +1,34 @@
+/*=========================================================================
+
+  Program:   CMake - Cross-Platform Makefile Generator
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmMakefileUtilityTargetGenerator_h
+#define cmMakefileUtilityTargetGenerator_h
+
+#include "cmMakefileTargetGenerator.h"
+
+class cmMakefileUtilityTargetGenerator: 
+  public cmMakefileTargetGenerator
+{
+public:
+  /* the main entry point for this class. Writes the Makefiles associated
+     with this target */
+  virtual void WriteRuleFiles();  
+  
+protected:
+
+};
+
+#endif
-- 
GitLab