/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmMakefileTargetGenerator.h"

#include "cmGeneratorTarget.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmTarget.h"
#include "cmake.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratorExpression.h"

#include "cmMakefileExecutableTargetGenerator.h"
#include "cmMakefileLibraryTargetGenerator.h"
#include "cmMakefileUtilityTargetGenerator.h"

#include <ctype.h>

cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
  : OSXBundleGenerator(0)
  , MacOSXContentGenerator(0)
{
  this->BuildFileStream = 0;
  this->InfoFileStream = 0;
  this->FlagFileStream = 0;
  this->CustomCommandDriver = OnBuild;
  this->FortranModuleDirectoryComputed = false;
  this->Target = target;
  this->Makefile = this->Target->GetMakefile();
  this->LocalGenerator =
    static_cast<cmLocalUnixMakefileGenerator3*>(
      this->Makefile->GetLocalGenerator());
  this->ConfigName = this->LocalGenerator->ConfigurationName.c_str();
  this->GlobalGenerator =
    static_cast<cmGlobalUnixMakefileGenerator3*>(
      this->LocalGenerator->GetGlobalGenerator());
  this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
  cmake* cm = this->GlobalGenerator->GetCMakeInstance();
  this->NoRuleMessages = false;
  if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
    {
    this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
    }
  MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
}

cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
{
  delete MacOSXContentGenerator;
}

cmMakefileTargetGenerator *
cmMakefileTargetGenerator::New(cmGeneratorTarget *tgt)
{
  cmMakefileTargetGenerator *result = 0;

  switch (tgt->GetType())
    {
    case cmTarget::EXECUTABLE:
      result = new cmMakefileExecutableTargetGenerator(tgt);
      break;
    case cmTarget::STATIC_LIBRARY:
    case cmTarget::SHARED_LIBRARY:
    case cmTarget::MODULE_LIBRARY:
    case cmTarget::OBJECT_LIBRARY:
      result = new cmMakefileLibraryTargetGenerator(tgt);
      break;
    case cmTarget::UTILITY:
      result = new cmMakefileUtilityTargetGenerator(tgt);
      break;
    default:
      return result;
      // break; /* unreachable */
    }
  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";

  // Construct the rule file name.
  this->ProgressFileNameFull = this->TargetBuildDirectoryFull;
  this->ProgressFileNameFull += "/progress.make";

  // reset the progress count
  this->NumberOfProgressActions = 0;

  // 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);
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
  const std::string& config =
    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");

  // 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"))
    {
    cmGeneratorExpression ge;
    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
                                            ge.Parse(additional_clean_files);

    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config,
                                                  false, this->Target, 0, 0),
                                      this->CleanFiles);
    }

  // 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);

  // First generate the object rule files.  Save a list of all object
  // files for this target.
  std::vector<cmSourceFile const*> customCommands;
  this->GeneratorTarget->GetCustomCommands(customCommands, config);
  for(std::vector<cmSourceFile const*>::const_iterator
        si = customCommands.begin();
      si != customCommands.end(); ++si)
    {
    cmCustomCommandGenerator ccg(*(*si)->GetCustomCommand(),
                                 this->ConfigName,
                                 this->Makefile);
    this->GenerateCustomRuleFile(ccg);
    if (clean)
      {
      const std::vector<std::string>& outputs = ccg.GetOutputs();
      for(std::vector<std::string>::const_iterator o = outputs.begin();
          o != outputs.end(); ++o)
        {
        this->CleanFiles.push_back
          (this->Convert(*o,
                         cmLocalGenerator::START_OUTPUT,
                         cmLocalGenerator::UNCHANGED));
        }
      }
    }
  std::vector<cmSourceFile const*> headerSources;
  this->GeneratorTarget->GetHeaderSources(headerSources, config);
  this->OSXBundleGenerator->GenerateMacOSXContentStatements(
    headerSources,
    this->MacOSXContentGenerator);
  std::vector<cmSourceFile const*> extraSources;
  this->GeneratorTarget->GetExtraSources(extraSources, config);
  this->OSXBundleGenerator->GenerateMacOSXContentStatements(
    extraSources,
    this->MacOSXContentGenerator);
  std::vector<cmSourceFile const*> externalObjects;
  this->GeneratorTarget->GetExternalObjects(externalObjects, config);
  for(std::vector<cmSourceFile const*>::const_iterator
        si = externalObjects.begin();
      si != externalObjects.end(); ++si)
    {
    this->ExternalObjects.push_back((*si)->GetFullPath());
    }
  std::vector<cmSourceFile const*> objectSources;
  this->GeneratorTarget->GetObjectSources(objectSources, config);
  for(std::vector<cmSourceFile const*>::const_iterator
        si = objectSources.begin(); si != objectSources.end(); ++si)
    {
    // Generate this object file's rule file.
    this->WriteObjectRuleFiles(**si);
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteCommonCodeRules()
{
  const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")?
                      "$(CMAKE_BINARY_DIR)/" : "");

  // 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->IncludeDirective << " " << root
    << this->Convert(dependFileNameFull,
                     cmLocalGenerator::HOME_OUTPUT,
                     cmLocalGenerator::MAKERULE)
    << "\n\n";

  if(!this->NoRuleMessages)
    {
    // Include the progress variables for the target.
    *this->BuildFileStream
      << "# Include the progress variables for this target.\n"
      << this->LocalGenerator->IncludeDirective << " " << root
      << this->Convert(this->ProgressFileNameFull,
                       cmLocalGenerator::HOME_OUTPUT,
                       cmLocalGenerator::MAKERULE)
      << "\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->IncludeDirective << " " << root
    << this->Convert(this->FlagFileNameFull,
                                     cmLocalGenerator::HOME_OUTPUT,
                                     cmLocalGenerator::MAKERULE)
    << "\n\n";
}

//----------------------------------------------------------------------------
std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
{
  ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
  if (i == this->FlagsByLanguage.end())
    {
    std::string flags;
    const char *lang = l.c_str();

    // Add language feature flags.
    this->AddFeatureFlags(flags, lang);

    this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
                                               lang, this->ConfigName);

    // Fortran-specific flags computed for this target.
    if(l == "Fortran")
      {
      this->AddFortranFlags(flags);
      }

    this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
                                          lang, this->ConfigName);

    this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
                                                   lang);

    // Add include directory flags.
    this->AddIncludeFlags(flags, lang);

    // Append old-style preprocessor definition flags.
    this->LocalGenerator->
      AppendFlags(flags, this->Makefile->GetDefineFlags());

    // Add include directory flags.
    this->LocalGenerator->
      AppendFlags(flags,this->GetFrameworkFlags(l));

    // Add target-specific flags.
    this->LocalGenerator->AddCompileOptions(flags, this->Target,
                                            lang, this->ConfigName);

    ByLanguageMap::value_type entry(l, flags);
    i = this->FlagsByLanguage.insert(entry).first;
    }
  return i->second;
}

std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
{
  ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
  if (i == this->DefinesByLanguage.end())
    {
    std::set<std::string> defines;
    const char *lang = l.c_str();
    // Add the export symbol definition for shared library objects.
    if(const char* exportMacro = this->Target->GetExportMacro())
      {
      this->LocalGenerator->AppendDefines(defines, exportMacro);
      }

    // Add preprocessor definitions for this target and configuration.
    this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
                            this->LocalGenerator->ConfigurationName);

    std::string definesString;
    this->LocalGenerator->JoinDefines(defines, definesString, lang);

    ByLanguageMap::value_type entry(l, definesString);
    i = this->DefinesByLanguage.insert(entry).first;
    }
  return i->second;
}

void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
{
  // write language flags for target
  std::set<std::string> languages;
  this->Target->GetLanguages(languages,
                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
  // put the compiler in the rules.make file so that if it changes
  // things rebuild
  for(std::set<std::string>::const_iterator l = languages.begin();
      l != languages.end(); ++l)
    {
    std::string compiler = "CMAKE_";
    compiler += *l;
    compiler += "_COMPILER";
    *this->FlagFileStream << "# compile " << *l << " with " <<
      this->Makefile->GetSafeDefinition(compiler) << "\n";
    }

  for(std::set<std::string>::const_iterator l = languages.begin();
      l != languages.end(); ++l)
    {
    std::string flags = this->GetFlags(*l);
    std::string defines = this->GetDefines(*l);
    // Escape comment characters so they do not terminate assignment.
    cmSystemTools::ReplaceString(flags, "#", "\\#");
    cmSystemTools::ReplaceString(defines, "#", "\\#");
    *this->FlagFileStream << *l << "_FLAGS = " << flags << "\n\n";
    *this->FlagFileStream << *l << "_DEFINES = " << defines << "\n\n";
    }
}


//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
  (cmSourceFile const& source, const char* pkgloc)
{
  // Skip OS X content when not building a Framework or Bundle.
  if(!this->Generator->GetTarget()->IsBundleOnApple())
    {
    return;
    }

  std::string macdir =
    this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);

  // Get the input file location.
  std::string input = source.GetFullPath();

  // Get the output file location.
  std::string output = macdir;
  output += "/";
  output += cmSystemTools::GetFilenameName(input);
  this->Generator->CleanFiles.push_back(
    this->Generator->Convert(output,
                             cmLocalGenerator::START_OUTPUT));
  output = this->Generator->Convert(output,
                                    cmLocalGenerator::HOME_OUTPUT);

  // Create a rule to copy the content into the bundle.
  std::vector<std::string> depends;
  std::vector<std::string> commands;
  depends.push_back(input);
  std::string copyEcho = "Copying OS X content ";
  copyEcho += output;
  this->Generator->LocalGenerator->AppendEcho(
    commands, copyEcho.c_str(),
    cmLocalUnixMakefileGenerator3::EchoBuild);
  std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
  copyCommand += this->Generator->Convert(input,
                                          cmLocalGenerator::NONE,
                                          cmLocalGenerator::SHELL);
  copyCommand += " ";
  copyCommand += this->Generator->Convert(output,
                                          cmLocalGenerator::NONE,
                                          cmLocalGenerator::SHELL);
  commands.push_back(copyCommand);
  this->Generator->LocalGenerator->WriteMakeRule(
    *this->Generator->BuildFileStream, 0,
    output,
    depends, commands, false);
  this->Generator->ExtraFiles.insert(output);
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::WriteObjectRuleFiles(cmSourceFile const& source)
{
  // Identify the language of the source file.
  const std::string& lang =
    this->LocalGenerator->GetSourceFileLanguage(source);
  if(lang.empty())
    {
    // don't know anything about this file so skip it
    return;
    }

  // Get the full path name of the object file.
  std::string const& objectName = this->GeneratorTarget
                                      ->GetObjectName(&source);
  std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target);
  obj += "/";
  obj += objectName;

  // Avoid generating duplicate rules.
  if(this->ObjectFiles.find(obj) == this->ObjectFiles.end())
    {
    this->ObjectFiles.insert(obj);
    }
  else
    {
    cmOStringStream err;
    err << "Warning: Source file \""
        << source.GetFullPath()
        << "\" 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);
  cmSystemTools::MakeDirectory
    (this->LocalGenerator->ConvertToFullPath(dir).c_str());

  // Save this in the target's list of object files.
  this->Objects.push_back(obj);
  this->CleanFiles.push_back(obj);

  // TODO: Remove
  //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.
  std::string objFullPath = this->Makefile->GetCurrentOutputDirectory();
  objFullPath += "/";
  objFullPath += obj;
  objFullPath =
    this->Convert(objFullPath, cmLocalGenerator::FULL);
  std::string srcFullPath =
    this->Convert(source.GetFullPath(), cmLocalGenerator::FULL);
  this->LocalGenerator->
    AddImplicitDepends(*this->Target, lang,
                       objFullPath.c_str(),
                       srcFullPath.c_str());
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source)
{
  const char* srcfmt = source.GetProperty("Fortran_FORMAT");
  cmLocalGenerator::FortranFormat format =
    this->LocalGenerator->GetFortranFormat(srcfmt);
  if(format == cmLocalGenerator::FortranFormatNone)
    {
    const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
    format = this->LocalGenerator->GetFortranFormat(tgtfmt);
    }
  const char* var = 0;
  switch (format)
    {
    case cmLocalGenerator::FortranFormatFixed:
      var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
    case cmLocalGenerator::FortranFormatFree:
      var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
    default: break;
    }
  if(var)
    {
    this->LocalGenerator->AppendFlags(
      flags, this->Makefile->GetDefinition(var));
    }
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::WriteObjectBuildFile(std::string &obj,
                       const std::string& lang,
                       cmSourceFile const& source,
                       std::vector<std::string>& depends)
{
  this->LocalGenerator->AppendRuleDepend(depends,
                                         this->FlagFileNameFull.c_str());
  this->LocalGenerator->AppendRuleDepends(depends,
                                          this->FlagFileDepends[lang]);

  // generate the depend scanning rule
  this->WriteObjectDependRules(source, depends);

  std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath();
  relativeObj += obj;
  // Write the build rule.

  // Build the set of compiler flags.
  std::string flags;

  // Add language-specific flags.
  std::string langFlags = "$(";
  langFlags += lang;
  langFlags += "_FLAGS)";
  this->LocalGenerator->AppendFlags(flags, langFlags);

  std::string configUpper =
    cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);

  // Add Fortran format flags.
  if(lang == "Fortran")
    {
    this->AppendFortranFormatFlags(flags, source);
    }

  // 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 defines.
  std::set<std::string> defines;

  // Add source-sepcific preprocessor definitions.
  if(const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS"))
    {
    this->LocalGenerator->AppendDefines(defines, compile_defs);
    *this->FlagFileStream << "# Custom defines: "
                          << relativeObj << "_DEFINES = "
                          << compile_defs << "\n"
                          << "\n";
    }
  std::string defPropName = "COMPILE_DEFINITIONS_";
  defPropName += configUpper;
  if(const char* config_compile_defs =
     source.GetProperty(defPropName))
    {
    this->LocalGenerator->AppendDefines(defines, config_compile_defs);
    *this->FlagFileStream
      << "# Custom defines: "
      << relativeObj << "_DEFINES_" << configUpper
      << " = " << config_compile_defs << "\n"
      << "\n";
    }

  // Get the output paths for source and object files.
  std::string sourceFile = source.GetFullPath();
  if(this->LocalGenerator->UseRelativePaths)
    {
    sourceFile = this->Convert(sourceFile,
                               cmLocalGenerator::START_OUTPUT);
    }
  sourceFile = this->Convert(sourceFile,
                             cmLocalGenerator::NONE,
                             cmLocalGenerator::SHELL);

  // Construct the build message.
  std::vector<std::string> no_commands;
  std::vector<std::string> commands;

  // add in a progress call if needed
  this->AppendProgress(commands);

  if(!this->NoRuleMessages)
    {
    std::string buildEcho = "Building ";
    buildEcho += lang;
    buildEcho += " object ";
    buildEcho += relativeObj;
    this->LocalGenerator->AppendEcho
      (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
    }

  std::string targetOutPathReal;
  std::string targetOutPathPDB;
  std::string targetOutPathCompilePDB;
  {
  std::string targetFullPathReal;
  std::string targetFullPathPDB;
  std::string targetFullPathCompilePDB;
  if(this->Target->GetType() == cmTarget::EXECUTABLE ||
     this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
     this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
     this->Target->GetType() == cmTarget::MODULE_LIBRARY)
    {
    targetFullPathReal =
      this->Target->GetFullPath(this->ConfigName, false, true);
    targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
    targetFullPathPDB += "/";
    targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
    }
  if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
    {
    targetFullPathCompilePDB =
      this->Target->GetCompilePDBPath(this->ConfigName);
    if(targetFullPathCompilePDB.empty())
      {
      targetFullPathCompilePDB = this->Target->GetSupportDirectory() + "/";
      }
    }

  targetOutPathReal = this->Convert(targetFullPathReal,
                                    cmLocalGenerator::START_OUTPUT,
                                    cmLocalGenerator::SHELL);
  targetOutPathPDB =
    this->Convert(targetFullPathPDB,cmLocalGenerator::NONE,
                  cmLocalGenerator::SHELL);
  targetOutPathCompilePDB =
    this->Convert(targetFullPathCompilePDB,
                  cmLocalGenerator::START_OUTPUT,
                  cmLocalGenerator::SHELL);
  }
  cmLocalGenerator::RuleVariables vars;
  vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
  vars.CMTarget = this->Target;
  vars.Language = lang.c_str();
  vars.Target = targetOutPathReal.c_str();
  vars.TargetPDB = targetOutPathPDB.c_str();
  vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
  vars.Source = sourceFile.c_str();
  std::string shellObj =
    this->Convert(obj,
                  cmLocalGenerator::NONE,
                  cmLocalGenerator::SHELL);
  vars.Object = shellObj.c_str();
  std::string objectDir = this->Target->GetSupportDirectory();
  objectDir = this->Convert(objectDir,
                            cmLocalGenerator::START_OUTPUT,
                            cmLocalGenerator::SHELL);
  vars.ObjectDir = objectDir.c_str();
  std::string objectFileDir = cmSystemTools::GetFilenamePath(obj);
  objectFileDir = this->Convert(objectFileDir,
                                cmLocalGenerator::START_OUTPUT,
                                cmLocalGenerator::SHELL);
  vars.ObjectFileDir = objectFileDir.c_str();
  vars.Flags = flags.c_str();

  std::string definesString = "$(";
  definesString += lang;
  definesString += "_DEFINES)";

  this->LocalGenerator->JoinDefines(defines, definesString, lang);

  vars.Defines = definesString.c_str();

  bool lang_is_c_or_cxx = ((lang == "C") || (lang == "CXX"));

  // Construct the compile rules.
  {
  std::string compileRuleVar = "CMAKE_";
  compileRuleVar += lang;
  compileRuleVar += "_COMPILE_OBJECT";
  std::string compileRule =
    this->Makefile->GetRequiredDefinition(compileRuleVar);
  std::vector<std::string> compileCommands;
  cmSystemTools::ExpandListArgument(compileRule, compileCommands);

  if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
      lang_is_c_or_cxx && compileCommands.size() == 1)
    {
    std::string compileCommand = compileCommands[0];
    this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
    std::string workingDirectory =
      this->LocalGenerator->Convert(
        this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
    compileCommand.replace(compileCommand.find(langFlags),
                           langFlags.size(), this->GetFlags(lang));
    std::string langDefines = std::string("$(") + lang + "_DEFINES)";
    compileCommand.replace(compileCommand.find(langDefines),
                           langDefines.size(), this->GetDefines(lang));
    this->GlobalGenerator->AddCXXCompileCommand(
      source.GetFullPath(), workingDirectory, compileCommand);
    }

  // Expand placeholders in the commands.
  for(std::vector<std::string>::iterator i = compileCommands.begin();
      i != compileCommands.end(); ++i)
    {
    this->LocalGenerator->ExpandRuleVariables(*i, vars);
    }

  // Change the command working directory to the local build tree.
  this->LocalGenerator->CreateCDCommand
    (compileCommands,
     this->Makefile->GetStartOutputDirectory(),
     cmLocalGenerator::HOME_OUTPUT);
  commands.insert(commands.end(),
                  compileCommands.begin(), compileCommands.end());
  }

  // Write the rule.
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                      relativeObj,
                                      depends, commands, false);

  // Check for extra outputs created by the compilation.
  if(const char* extra_outputs_str =
     source.GetProperty("OBJECT_OUTPUTS"))
    {
    std::vector<std::string> extra_outputs;
    cmSystemTools::ExpandListArgument(extra_outputs_str, extra_outputs);
    for(std::vector<std::string>::const_iterator eoi = extra_outputs.begin();
        eoi != extra_outputs.end(); ++eoi)
      {
      // Register this as an extra output for the object file rule.
      // This will cause the object file to be rebuilt if the extra
      // output is missing.
      this->GenerateExtraOutput(eoi->c_str(), relativeObj.c_str(), false);

      // Register this as an extra file to clean.
      this->CleanFiles.push_back(*eoi);
      }
    }

  bool do_preprocess_rules = lang_is_c_or_cxx &&
    this->LocalGenerator->GetCreatePreprocessedSourceRules();
  bool do_assembly_rules = lang_is_c_or_cxx &&
    this->LocalGenerator->GetCreateAssemblySourceRules();
  if(do_preprocess_rules || do_assembly_rules)
    {
    std::vector<std::string> force_depends;
    force_depends.push_back("cmake_force");
    std::string::size_type dot_pos = relativeObj.rfind(".");
    std::string relativeObjBase = relativeObj.substr(0, dot_pos);
    dot_pos = obj.rfind(".");
    std::string objBase = obj.substr(0, dot_pos);

    if(do_preprocess_rules)
      {
      commands.clear();
      std::string relativeObjI = relativeObjBase + ".i";
      std::string objI = objBase + ".i";

      std::string preprocessEcho = "Preprocessing ";
      preprocessEcho += lang;
      preprocessEcho += " source to ";
      preprocessEcho += objI;
      this->LocalGenerator->AppendEcho(
        commands, preprocessEcho.c_str(),
        cmLocalUnixMakefileGenerator3::EchoBuild
        );

      std::string preprocessRuleVar = "CMAKE_";
      preprocessRuleVar += lang;
      preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE";
      if(const char* preprocessRule =
         this->Makefile->GetDefinition(preprocessRuleVar))
        {
        std::vector<std::string> preprocessCommands;
        cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);

        std::string shellObjI =
          this->Convert(objI,
                        cmLocalGenerator::NONE,
                        cmLocalGenerator::SHELL);
        vars.PreprocessedSource = shellObjI.c_str();

        // Expand placeholders in the commands.
        for(std::vector<std::string>::iterator i = preprocessCommands.begin();
            i != preprocessCommands.end(); ++i)
          {
          this->LocalGenerator->ExpandRuleVariables(*i, vars);
          }

        this->LocalGenerator->CreateCDCommand
          (preprocessCommands,
           this->Makefile->GetStartOutputDirectory(),
           cmLocalGenerator::HOME_OUTPUT);
        commands.insert(commands.end(),
                        preprocessCommands.begin(),
                        preprocessCommands.end());
        }
      else
        {
        std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
        cmd += preprocessRuleVar;
        commands.push_back(cmd);
        }

      this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                          relativeObjI,
                                          force_depends, commands, false);
      }

    if(do_assembly_rules)
      {
      commands.clear();
      std::string relativeObjS = relativeObjBase + ".s";
      std::string objS = objBase + ".s";

      std::string assemblyEcho = "Compiling ";
      assemblyEcho += lang;
      assemblyEcho += " source to assembly ";
      assemblyEcho += objS;
      this->LocalGenerator->AppendEcho(
        commands, assemblyEcho.c_str(),
        cmLocalUnixMakefileGenerator3::EchoBuild
        );

      std::string assemblyRuleVar = "CMAKE_";
      assemblyRuleVar += lang;
      assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE";
      if(const char* assemblyRule =
         this->Makefile->GetDefinition(assemblyRuleVar))
        {
        std::vector<std::string> assemblyCommands;
        cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);

        std::string shellObjS =
          this->Convert(objS,
                        cmLocalGenerator::NONE,
                        cmLocalGenerator::SHELL);
        vars.AssemblySource = shellObjS.c_str();

        // Expand placeholders in the commands.
        for(std::vector<std::string>::iterator i = assemblyCommands.begin();
            i != assemblyCommands.end(); ++i)
          {
          this->LocalGenerator->ExpandRuleVariables(*i, vars);
          }

        this->LocalGenerator->CreateCDCommand
          (assemblyCommands,
           this->Makefile->GetStartOutputDirectory(),
           cmLocalGenerator::HOME_OUTPUT);
        commands.insert(commands.end(),
                        assemblyCommands.begin(),
                        assemblyCommands.end());
        }
      else
        {
        std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
        cmd += assemblyRuleVar;
        commands.push_back(cmd);
        }

      this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                          relativeObjS,
                                          force_depends, commands, false);
      }
    }

  // 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, p_depends,
                                      no_commands, true);

  // 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));

  p_depends.clear();
  p_depends.push_back(objectRequires);
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                      objectProvides, p_depends,
                                      r_commands, true);

  // 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, p_depends, no_commands,
                                      false);
}

//----------------------------------------------------------------------------
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,
                                      depends, no_commands, true);
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetCleanRules()
{
  std::vector<std::string> depends;
  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->Target);
  this->LocalGenerator->CreateCDCommand
    (commands,
     this->Makefile->GetStartOutputDirectory(),
     cmLocalGenerator::HOME_OUTPUT);

  // Write the rule.
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                      cleanTarget,
                                      depends, commands, true);
}


//----------------------------------------------------------------------------
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);

  // Store multiple output pairs in the depend info file.
  if(!this->MultipleOutputPairs.empty())
    {
    *this->InfoFileStream
      << "\n"
      << "# Pairs of files generated by the same build rule.\n"
      << "set(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
    for(MultipleOutputPairsType::const_iterator pi =
          this->MultipleOutputPairs.begin();
        pi != this->MultipleOutputPairs.end(); ++pi)
      {
      *this->InfoFileStream
        << "  " << this->LocalGenerator->EscapeForCMake(pi->first)
        << " "  << this->LocalGenerator->EscapeForCMake(pi->second)
        << "\n";
      }
    *this->InfoFileStream << "  )\n\n";
    }

  // Store list of targets linked directly or transitively.
  {
  *this->InfoFileStream
    << "\n"
    << "# Targets to which this target links.\n"
    << "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
  std::set<cmTarget const*> emitted;
  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
    {
    cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
    for(cmComputeLinkInformation::ItemVector::const_iterator
          i = items.begin(); i != items.end(); ++i)
      {
      cmTarget const* linkee = i->Target;
      if(linkee && !linkee->IsImported()
                // We can ignore the INTERFACE_LIBRARY items because
                // Target->GetLinkInformation already processed their
                // link interface and they don't have any output themselves.
                && linkee->GetType() != cmTarget::INTERFACE_LIBRARY
                && emitted.insert(linkee).second)
        {
        cmMakefile* mf = linkee->GetMakefile();
        cmLocalGenerator* lg = mf->GetLocalGenerator();
        std::string di = mf->GetStartOutputDirectory();
        di += "/";
        di += lg->GetTargetDirectory(*linkee);
        di += "/DependInfo.cmake";
        *this->InfoFileStream << "  \"" << di << "\"\n";
        }
      }
    }
  *this->InfoFileStream
    << "  )\n";
  }

  // Check for a target-specific module output directory.
  if(const char* mdir = this->GetFortranModuleDirectory())
    {
    *this->InfoFileStream
      << "\n"
      << "# Fortran module output directory.\n"
      << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
    }

  // Target-specific include directories:
  *this->InfoFileStream
    << "\n"
    << "# The include file search paths:\n";
  *this->InfoFileStream
    << "set(CMAKE_C_TARGET_INCLUDE_PATH\n";
  std::vector<std::string> includes;

  const std::string& config =
    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  this->LocalGenerator->GetIncludeDirectories(includes,
                                              this->GeneratorTarget,
                                              "C", config);
  for(std::vector<std::string>::iterator i = includes.begin();
      i != includes.end(); ++i)
    {
    *this->InfoFileStream
      << "  \""
      << this->LocalGenerator->Convert(*i,
                                       cmLocalGenerator::HOME_OUTPUT)
      << "\"\n";
    }
  *this->InfoFileStream
    << "  )\n";
  *this->InfoFileStream
    << "set(CMAKE_CXX_TARGET_INCLUDE_PATH "
    << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
  *this->InfoFileStream
    << "set(CMAKE_Fortran_TARGET_INCLUDE_PATH "
    << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
  *this->InfoFileStream
    << "set(CMAKE_ASM_TARGET_INCLUDE_PATH "
    << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";

  // 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";

  // 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.
#if !defined(_WIN32) || defined(__CYGWIN__)
  // This platform supports symlinks, so cmSystemTools will translate
  // paths.  Make sure PWD is set to the original name of the home
  // output directory to help cmSystemTools to create the same
  // translation table for the dependency scanning process.
  depCmd << "cd "
         << (this->LocalGenerator->Convert(
               this->Makefile->GetHomeOutputDirectory(),
               cmLocalGenerator::FULL, cmLocalGenerator::SHELL))
         << " && ";
#endif
  // Generate a call this signature:
  //
  //   cmake -E cmake_depends <generator>
  //                          <home-src-dir> <start-src-dir>
  //                          <home-out-dir> <start-out-dir>
  //                          <dep-info> --color=$(COLOR)
  //
  // This gives the dependency scanner enough information to recreate
  // the state of our local generator sufficiently for its needs.
  depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
         << this->GlobalGenerator->GetName() << "\" "
         << this->Convert(this->Makefile->GetHomeDirectory(),
                          cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
         << " "
         << this->Convert(this->Makefile->GetStartDirectory(),
                          cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
         << " "
         << this->Convert(this->Makefile->GetHomeOutputDirectory(),
                          cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
         << " "
         << this->Convert(this->Makefile->GetStartOutputDirectory(),
                          cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
         << " "
         << this->Convert(this->InfoFileNameFull,
                          cmLocalGenerator::FULL, cmLocalGenerator::SHELL);
  if(this->LocalGenerator->GetColorMakefile())
    {
    depCmd << " --color=$(COLOR)";
    }
  commands.push_back(depCmd.str());

  // Make sure all custom command outputs in this target are built.
  if(this->CustomCommandDriver == OnDepends)
    {
    this->DriveCustomCommands(depends);
    }

  // Write the rule.
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                      depTarget,
                                      depends, commands, true);
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::DriveCustomCommands(std::vector<std::string>& depends)
{
  // Depend on all custom command outputs.
  std::vector<cmSourceFile*> sources;
  this->Target->GetSourceFiles(sources,
                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
  for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
      source != sources.end(); ++source)
    {
    if(cmCustomCommand* cc = (*source)->GetCustomCommand())
      {
      cmCustomCommandGenerator ccg(*cc, this->ConfigName, this->Makefile);
      const std::vector<std::string>& outputs = ccg.GetOutputs();
      for(std::vector<std::string>::const_iterator o = outputs.begin();
          o != outputs.end(); ++o)
        {
        depends.push_back(*o);
        }
      }
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::WriteObjectDependRules(cmSourceFile const& 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);
      }
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg)
{
  // Collect the commands.
  std::vector<std::string> commands;
  std::string comment = this->LocalGenerator->ConstructComment(ccg);
  if(!comment.empty())
    {
    // add in a progress call if needed
    this->AppendProgress(commands);
    if(!this->NoRuleMessages)
      {
      this->LocalGenerator
        ->AppendEcho(commands, comment.c_str(),
                     cmLocalUnixMakefileGenerator3::EchoGenerate);
      }
    }

  // Now append the actual user-specified commands.
  cmOStringStream content;
  this->LocalGenerator->AppendCustomCommand(commands, ccg, this->Target, false,
                                            cmLocalGenerator::HOME_OUTPUT,
                                            &content);

  // Collect the dependencies.
  std::vector<std::string> depends;
  this->LocalGenerator->AppendCustomDepend(depends, ccg);

  // Check whether we need to bother checking for a symbolic output.
  bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();

  // Write the rule.
  const std::vector<std::string>& outputs = ccg.GetOutputs();
  std::vector<std::string>::const_iterator o = outputs.begin();
  {
  bool symbolic = false;
  if(need_symbolic)
    {
    if(cmSourceFile* sf = this->Makefile->GetSource(*o))
      {
      symbolic = sf->GetPropertyAsBool("SYMBOLIC");
      }
    }
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                      *o, depends, commands,
                                      symbolic);

  // If the rule has changed make sure the output is rebuilt.
  if(!symbolic)
    {
    this->GlobalGenerator->AddRuleHash(ccg.GetOutputs(), content.str());
    }
  }

  // Write rules to drive building any outputs beyond the first.
  const char* in = o->c_str();
  for(++o; o != outputs.end(); ++o)
    {
    bool symbolic = false;
    if(need_symbolic)
      {
      if(cmSourceFile* sf = this->Makefile->GetSource(*o))
        {
        symbolic = sf->GetPropertyAsBool("SYMBOLIC");
        }
      }
    this->GenerateExtraOutput(o->c_str(), in, symbolic);
    }

  // Setup implicit dependency scanning.
  for(cmCustomCommand::ImplicitDependsList::const_iterator
        idi = ccg.GetCC().GetImplicitDepends().begin();
      idi != ccg.GetCC().GetImplicitDepends().end(); ++idi)
    {
    std::string objFullPath =
      this->Convert(outputs[0], cmLocalGenerator::FULL);
    std::string srcFullPath =
      this->Convert(idi->second, cmLocalGenerator::FULL);
    this->LocalGenerator->
      AddImplicitDepends(*this->Target, idi->first,
                         objFullPath.c_str(),
                         srcFullPath.c_str());
    }
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::GenerateExtraOutput(const char* out, const char* in, bool symbolic)
{
  // Add a rule to build the primary output if the extra output needs
  // to be created.
  std::vector<std::string> commands;
  std::vector<std::string> depends;
  std::string emptyCommand = this->GlobalGenerator->GetEmptyRuleHackCommand();
  if(!emptyCommand.empty())
    {
    commands.push_back(emptyCommand);
    }
  depends.push_back(in);
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
                                      out, depends, commands,
                                      symbolic);

  // Register the extra output as paired with the first output so that
  // the check-build-system step will remove the primary output if any
  // extra outputs are missing.  This forces the rule to regenerate
  // all outputs.
  this->AddMultipleOutputPair(out, in);
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands)
{
  this->NumberOfProgressActions++;
  if(this->NoRuleMessages)
    {
    return;
    }
  std::string progressDir = this->Makefile->GetHomeOutputDirectory();
  progressDir += cmake::GetCMakeFilesDirectory();
  cmOStringStream progCmd;
  progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
  progCmd << this->LocalGenerator->Convert(progressDir,
                                           cmLocalGenerator::FULL,
                                           cmLocalGenerator::SHELL);
  progCmd << " $(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")";
  commands.push_back(progCmd.str());
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::WriteObjectsVariable(std::string& variableName,
                       std::string& variableNameExternal,
                       bool useWatcomQuote)
{
  // 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 << " =";
  std::string object;
  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";
    *this->BuildFileStream  <<
      this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str(),
                                                      useWatcomQuote);
    }
  *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 << " =";
  for(std::vector<std::string>::const_iterator i =
        this->ExternalObjects.begin();
      i != this->ExternalObjects.end(); ++i)
    {
    object = this->Convert(*i,cmLocalGenerator::START_OUTPUT);
    *this->BuildFileStream
      << " " << lineContinue << "\n"
      << this->Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME");
    *this->BuildFileStream  <<
      this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str(),
                                                      useWatcomQuote);
    }
  *this->BuildFileStream << "\n" << "\n";
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::WriteObjectsString(std::string& buildObjs)
{
  std::vector<std::string> objStrings;
  this->WriteObjectsStrings(objStrings);
  buildObjs = objStrings[0];
}

//----------------------------------------------------------------------------
class cmMakefileTargetGeneratorObjectStrings
{
public:
  cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings,
                                         cmLocalUnixMakefileGenerator3* lg,
                                         std::string::size_type limit):
    Strings(strings), LocalGenerator(lg), LengthLimit(limit)
    {
    this->Space = "";
    }
  void Feed(std::string const& obj)
    {
    // Construct the name of the next object.
    this->NextObject =
      this->LocalGenerator->Convert(obj,
                                    cmLocalGenerator::START_OUTPUT,
                                    cmLocalGenerator::RESPONSE);

    // Roll over to next string if the limit will be exceeded.
    if(this->LengthLimit != std::string::npos &&
       (this->CurrentString.length() + 1 + this->NextObject.length()
        > this->LengthLimit))
      {
      this->Strings.push_back(this->CurrentString);
      this->CurrentString = "";
      this->Space = "";
      }

    // Separate from previous object.
    this->CurrentString += this->Space;
    this->Space = " ";

    // Append this object.
    this->CurrentString += this->NextObject;
    }
  void Done()
    {
    this->Strings.push_back(this->CurrentString);
    }
private:
  std::vector<std::string>& Strings;
  cmLocalUnixMakefileGenerator3* LocalGenerator;
  std::string::size_type LengthLimit;
  std::string CurrentString;
  std::string NextObject;
  const char* Space;
};

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::WriteObjectsStrings(std::vector<std::string>& objStrings,
                      std::string::size_type limit)
{
  cmMakefileTargetGeneratorObjectStrings
    helper(objStrings, this->LocalGenerator, limit);
  for(std::vector<std::string>::const_iterator i = this->Objects.begin();
      i != this->Objects.end(); ++i)
    {
    helper.Feed(*i);
    }
  for(std::vector<std::string>::const_iterator i =
        this->ExternalObjects.begin();
      i != this->ExternalObjects.end(); ++i)
    {
    helper.Feed(*i);
    }
  helper.Done();
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetDriverRule(
                                                const std::string& main_output,
                                                bool relink)
{
  // Compute the name of the driver target.
  std::string dir =
    this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
  std::string buildTargetRuleName = dir;
  buildTargetRuleName += relink?"/preinstall":"/build";
  buildTargetRuleName = this->Convert(buildTargetRuleName,
                                      cmLocalGenerator::HOME_OUTPUT,
                                      cmLocalGenerator::UNCHANGED);

  // Build the list of target outputs to drive.
  std::vector<std::string> depends;
  depends.push_back(main_output);

  const char* comment = 0;
  if(relink)
    {
    // Setup the comment for the preinstall driver.
    comment = "Rule to relink during preinstall.";
    }
  else
    {
    // Setup the comment for the main build driver.
    comment = "Rule to build all files generated by this target.";

    // Make sure all custom command outputs in this target are built.
    if(this->CustomCommandDriver == OnBuild)
      {
      this->DriveCustomCommands(depends);
      }

    // Make sure the extra files are built.
    for(std::set<std::string>::const_iterator i = this->ExtraFiles.begin();
        i != this->ExtraFiles.end(); ++i)
      {
      depends.push_back(*i);
      }
    }

  // Write the driver rule.
  std::vector<std::string> no_commands;
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment,
                                      buildTargetRuleName,
                                      depends, no_commands, true);
}

//----------------------------------------------------------------------------
std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l)
{
 if(!this->Makefile->IsOn("APPLE"))
   {
   return std::string();
   }

  std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG";
  const char* fwSearchFlag =
    this->Makefile->GetDefinition(fwSearchFlagVar);
  if(!(fwSearchFlag && *fwSearchFlag))
    {
    return std::string();
    }

 std::set<std::string> emitted;
#ifdef __APPLE__  /* don't insert this when crosscompiling e.g. to iphone */
  emitted.insert("/System/Library/Frameworks");
#endif
  std::vector<std::string> includes;

  const std::string& config =
    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  this->LocalGenerator->GetIncludeDirectories(includes,
                                              this->GeneratorTarget,
                                              "C", config);
  // check all include directories for frameworks as this
  // will already have added a -F for the framework
  for(std::vector<std::string>::iterator i = includes.begin();
      i != includes.end(); ++i)
    {
    if(this->Target->NameResolvesToFramework(*i))
      {
      std::string frameworkDir = *i;
      frameworkDir += "/../";
      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
      emitted.insert(frameworkDir);
      }
    }

  std::string flags;
  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
    {
    std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
    for(std::vector<std::string>::const_iterator i = frameworks.begin();
        i != frameworks.end(); ++i)
      {
      if(emitted.insert(*i).second)
        {
        flags += fwSearchFlag;
        flags += this->Convert(*i,
                               cmLocalGenerator::START_OUTPUT,
                               cmLocalGenerator::SHELL, true);
        flags += " ";
        }
      }
    }
  return flags;
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::AppendTargetDepends(std::vector<std::string>& depends)
{
  // Static libraries never depend on anything for linking.
  if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
    {
    return;
    }

  // Loop over all library dependencies.
  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
    {
    std::vector<std::string> const& libDeps = cli->GetDepends();
    for(std::vector<std::string>::const_iterator j = libDeps.begin();
        j != libDeps.end(); ++j)
      {
      depends.push_back(*j);
      }
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::AppendObjectDepends(std::vector<std::string>& depends)
{
  // Add dependencies on the compiled 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;
    depends.push_back(objTarget);
    }

  // Add dependencies on the external object files.
  for(std::vector<std::string>::const_iterator obj
        = this->ExternalObjects.begin();
      obj != this->ExternalObjects.end(); ++obj)
    {
    depends.push_back(*obj);
    }

  // Add a dependency on the rule file itself.
  this->LocalGenerator->AppendRuleDepend(depends,
                                         this->BuildFileNameFull.c_str());
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::AppendLinkDepends(std::vector<std::string>& depends)
{
  this->AppendObjectDepends(depends);

  // Add dependencies on targets that must be built first.
  this->AppendTargetDepends(depends);

  // Add a dependency on the link definitions file, if any.
  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
  if(!def.empty())
    {
    depends.push_back(def);
    }

  // Add user-specified dependencies.
  if(const char* linkDepends =
     this->Target->GetProperty("LINK_DEPENDS"))
    {
    cmSystemTools::ExpandListArgument(linkDepends, depends);
    }
}

//----------------------------------------------------------------------------
std::string cmMakefileTargetGenerator::GetLinkRule(
                                              const std::string& linkRuleVar)
{
  std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
  if(this->Target->HasImplibGNUtoMS())
    {
    std::string ruleVar = "CMAKE_";
    ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
    ruleVar += "_GNUtoMS_RULE";
    if(const char* rule = this->Makefile->GetDefinition(ruleVar))
      {
      linkRule += rule;
      }
    }
  return linkRule;
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::CloseFileStreams()
{
  delete this->BuildFileStream;
  delete this->InfoFileStream;
  delete this->FlagFileStream;
}

void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar,
                                                const std::string& linkLang,
                                                std::string& linkFlags)
{
  // check for language flags that are not allowed at link time, and
  // remove them, -w on darwin for gcc -w -dynamiclib sends -w to libtool
  // which fails, there may be more]

  std::string removeFlags = "CMAKE_";
  removeFlags += linkLang;
  removeFlags += flagVar;
  std::string removeflags =
    this->Makefile->GetSafeDefinition(removeFlags);
  std::vector<std::string> removeList;
  cmSystemTools::ExpandListArgument(removeflags, removeList);

  for(std::vector<std::string>::iterator i = removeList.begin();
      i != removeList.end(); ++i)
    {
    std::string tmp;
    std::string::size_type lastPosition = 0;

    for(;;)
      {
      std::string::size_type position = linkFlags.find(*i, lastPosition);

      if(position == std::string::npos)
        {
        tmp += linkFlags.substr(lastPosition);
        break;
        }
      else
        {
        std::string::size_type prefixLength = position - lastPosition;
        tmp += linkFlags.substr(lastPosition, prefixLength);
        lastPosition = position + i->length();

        bool validFlagStart = position == 0 ||
          isspace(linkFlags[position - 1]);

        bool validFlagEnd = lastPosition == linkFlags.size() ||
          isspace(linkFlags[lastPosition]);

        if(!validFlagStart || !validFlagEnd)
          {
          tmp += *i;
          }
        }
      }

    linkFlags = tmp;
    }
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::AddMultipleOutputPair(const char* depender, const char* dependee)
{
  MultipleOutputPairsType::value_type p(depender, dependee);
  this->MultipleOutputPairs.insert(p);
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::CreateLinkScript(const char* name,
                   std::vector<std::string> const& link_commands,
                   std::vector<std::string>& makefile_commands,
                   std::vector<std::string>& makefile_depends)
{
  // Create the link script file.
  std::string linkScriptName = this->TargetBuildDirectoryFull;
  linkScriptName += "/";
  linkScriptName += name;
  cmGeneratedFileStream linkScriptStream(linkScriptName.c_str());
  linkScriptStream.SetCopyIfDifferent(true);
  for(std::vector<std::string>::const_iterator cmd = link_commands.begin();
      cmd != link_commands.end(); ++cmd)
    {
    // Do not write out empty commands or commands beginning in the
    // shell no-op ":".
    if(!cmd->empty() && (*cmd)[0] != ':')
      {
      linkScriptStream << *cmd << "\n";
      }
    }

  // Create the makefile command to invoke the link script.
  std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
  link_command += this->Convert(linkScriptName,
                                cmLocalGenerator::START_OUTPUT,
                                cmLocalGenerator::SHELL);
  link_command += " --verbose=$(VERBOSE)";
  makefile_commands.push_back(link_command);
  makefile_depends.push_back(linkScriptName);
}

//----------------------------------------------------------------------------
std::string
cmMakefileTargetGenerator
::CreateResponseFile(const char* name, std::string const& options,
                     std::vector<std::string>& makefile_depends)
{
  // Create the response file.
  std::string responseFileNameFull = this->TargetBuildDirectoryFull;
  responseFileNameFull += "/";
  responseFileNameFull += name;
  cmGeneratedFileStream responseStream(responseFileNameFull.c_str());
  responseStream.SetCopyIfDifferent(true);
  responseStream << options << "\n";

  // Add a dependency so the target will rebuild when the set of
  // objects changes.
  makefile_depends.push_back(responseFileNameFull);

  // Construct the name to be used on the command line.
  std::string responseFileName = this->TargetBuildDirectory;
  responseFileName += "/";
  responseFileName += name;
  return responseFileName;
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::CreateLinkLibs(std::string& linkLibs, bool relink,
                 bool useResponseFile,
                 std::vector<std::string>& makefile_depends,
                 bool useWatcomQuote)
{
  std::string frameworkPath;
  std::string linkPath;
  this->LocalGenerator
    ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
                          *this->GeneratorTarget, relink,
                          useResponseFile,
                          useWatcomQuote);
  linkLibs = frameworkPath + linkPath + linkLibs;

  if(useResponseFile)
    {
    // Lookup the response file reference flag.
    std::string responseFlagVar = "CMAKE_";
    responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
    responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
    const char* responseFlag =
      this->Makefile->GetDefinition(responseFlagVar);
    if(!responseFlag)
      {
      responseFlag = "@";
      }

    // Create this response file.
    std::string link_rsp =
      this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends);

    // Reference the response file.
    linkLibs = responseFlag;
    linkLibs += this->Convert(link_rsp,
                              cmLocalGenerator::NONE,
                              cmLocalGenerator::SHELL);
    }
}

//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::CreateObjectLists(bool useLinkScript, bool useArchiveRules,
                    bool useResponseFile, std::string& buildObjs,
                    std::vector<std::string>& makefile_depends,
                    bool useWatcomQuote)
{
  std::string variableName;
  std::string variableNameExternal;
  this->WriteObjectsVariable(variableName, variableNameExternal,
                             useWatcomQuote);
  if(useResponseFile)
    {
    // MSVC response files cannot exceed 128K.
    std::string::size_type const responseFileLimit = 131000;

    // Construct the individual object list strings.
    std::vector<std::string> object_strings;
    this->WriteObjectsStrings(object_strings, responseFileLimit);

    // Lookup the response file reference flag.
    std::string responseFlagVar = "CMAKE_";
    responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
    responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
    const char* responseFlag =
      this->Makefile->GetDefinition(responseFlagVar);
    if(!responseFlag)
      {
      responseFlag = "@";
      }

    // Write a response file for each string.
    const char* sep = "";
    for(unsigned int i = 0; i < object_strings.size(); ++i)
      {
      // Number the response files.
      char rsp[32];
      sprintf(rsp, "objects%u.rsp", i+1);

      // Create this response file.
      std::string objects_rsp =
        this->CreateResponseFile(rsp, object_strings[i], makefile_depends);

      // Separate from previous response file references.
      buildObjs += sep;
      sep = " ";

      // Reference the response file.
      buildObjs += responseFlag;
      buildObjs += this->Convert(objects_rsp,
                                 cmLocalGenerator::NONE,
                                 cmLocalGenerator::SHELL);
      }
    }
  else if(useLinkScript)
    {
    if(!useArchiveRules)
      {
      this->WriteObjectsString(buildObjs);
      }
    }
  else
    {
    buildObjs = "$(";
    buildObjs += variableName;
    buildObjs += ") $(";
    buildObjs += variableNameExternal;
    buildObjs += ")";
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
                                                const std::string& lang)
{
  std::string responseVar = "CMAKE_";
  responseVar += lang;
  responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES";
  bool useResponseFile = this->Makefile->IsOn(responseVar);


  std::vector<std::string> includes;
  const std::string& config =
    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  this->LocalGenerator->GetIncludeDirectories(includes,
                                              this->GeneratorTarget,
                                              lang, config);

  std::string includeFlags =
    this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
                                          lang, false, useResponseFile);
  if(includeFlags.empty())
    {
    return;
    }

  if(useResponseFile)
    {
    std::string name = "includes_";
    name += lang;
    name += ".rsp";
    std::string arg = "@" +
      this->CreateResponseFile(name.c_str(), includeFlags,
                               this->FlagFileDepends[lang]);
    this->LocalGenerator->AppendFlags(flags, arg);
    }
  else
    {
    this->LocalGenerator->AppendFlags(flags, includeFlags);
    }
}

//----------------------------------------------------------------------------
const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
{
  // Compute the module directory.
  if(!this->FortranModuleDirectoryComputed)
    {
    const char* target_mod_dir =
      this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
    const char* moddir_flag =
      this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
    if(target_mod_dir && moddir_flag)
      {
      // Compute the full path to the module directory.
      if(cmSystemTools::FileIsFullPath(target_mod_dir))
        {
        // Already a full path.
        this->FortranModuleDirectory = target_mod_dir;
        }
      else
        {
        // Interpret relative to the current output directory.
        this->FortranModuleDirectory =
          this->Makefile->GetCurrentOutputDirectory();
        this->FortranModuleDirectory += "/";
        this->FortranModuleDirectory += target_mod_dir;
        }

      // Make sure the module output directory exists.
      cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str());
      }
    this->FortranModuleDirectoryComputed = true;
    }

  // Return the computed directory.
  if(this->FortranModuleDirectory.empty())
    {
    return 0;
    }
  else
    {
    return this->FortranModuleDirectory.c_str();
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
{
  // Enable module output if necessary.
  if(const char* modout_flag =
     this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
    {
    this->LocalGenerator->AppendFlags(flags, modout_flag);
    }

  // Add a module output directory flag if necessary.
  const char* mod_dir = this->GetFortranModuleDirectory();
  if(!mod_dir)
    {
    mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
    }
  if(mod_dir)
    {
    const char* moddir_flag =
      this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
    std::string modflag = moddir_flag;
    modflag += this->Convert(mod_dir,
                             cmLocalGenerator::START_OUTPUT,
                             cmLocalGenerator::SHELL);
    this->LocalGenerator->AppendFlags(flags, modflag);
    }

  // If there is a separate module path flag then duplicate the
  // include path with it.  This compiler does not search the include
  // path for modules.
  if(const char* modpath_flag =
     this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
    {
    std::vector<std::string> includes;
    const std::string& config =
      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
    this->LocalGenerator->GetIncludeDirectories(includes,
                                                this->GeneratorTarget,
                                                "C", config);
    for(std::vector<std::string>::const_iterator idi = includes.begin();
        idi != includes.end(); ++idi)
      {
      std::string flg = modpath_flag;
      flg += this->Convert(*idi,
                           cmLocalGenerator::NONE,
                           cmLocalGenerator::SHELL);
      this->LocalGenerator->AppendFlags(flags, flg);
      }
    }
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
{
  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
  if(def.empty())
    {
    return;
    }

  // TODO: Create a per-language flag variable.
  const char* defFileFlag =
    this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
  if(!defFileFlag)
    {
    return;
    }

  // Append the flag and value.  Use ConvertToLinkReference to help
  // vs6's "cl -link" pass it to the linker.
  std::string flag = defFileFlag;
  flag += (this->LocalGenerator->ConvertToLinkReference(def));
  this->LocalGenerator->AppendFlags(flags, flag);
}

//----------------------------------------------------------------------------
const char* cmMakefileTargetGenerator::GetFeature(const std::string& feature)
{
  return this->Target->GetFeature(feature, this->ConfigName);
}

//----------------------------------------------------------------------------
bool cmMakefileTargetGenerator::GetFeatureAsBool(const std::string& feature)
{
  return this->Target->GetFeatureAsBool(feature, this->ConfigName);
}

//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::AddFeatureFlags(
  std::string& flags, const std::string& lang
  )
{
  // Add language-specific flags.
  this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);

  if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
    {
    this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
    }
}
