/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 "cmLocalNMakeMakefileGenerator.h"
#include "cmMakefile.h"
#include "cmStandardIncludes.h"
#include "cmSystemTools.h"
#include "cmSourceFile.h"
#include "cmMakeDepend.h"
#include "cmCacheManager.h"
#include "cmGeneratedFileStream.h"
#include "windows.h"


cmLocalNMakeMakefileGenerator::cmLocalNMakeMakefileGenerator()
{
  this->SetLibraryPathOption("@CMAKE_C_LIBPATH_FLAG@"); // Use @ here
  this->SetObjectFileExtension("$(CMAKE_OBJECT_FILE_SUFFIX)");
  this->SetExecutableExtension("$(CMAKE_EXECUTABLE_SUFFIX)");
  this->SetLibraryPrefix("");
  this->SetStaticLibraryExtension("$(CMAKE_STATICLIB_SUFFIX)");
  this->SetSharedLibraryExtension("$(CMAKE_SHLIB_SUFFIX)");
}

cmLocalNMakeMakefileGenerator::~cmLocalNMakeMakefileGenerator()
{
}

// convert to windows short paths if there are spaces
// in path
std::string cmLocalNMakeMakefileGenerator::ShortPath(const char* path)
{
  std::string ret = path;
  // if there are no spaces in path, then just 
  // call ConvertToOutputPath
  if(ret.find(' ') == std::string::npos)
    {
    return cmSystemTools::ConvertToOutputPath(path);
    }
    
  // if there are spaces then call GetShortPathName to get rid of them
  if(!cmSystemTools::GetShortPath(path, ret))
    {
    // if GetShortPathName failed for some reason use
    // ConvertToOutputPath instead which will at least escape the spaces
    ret = cmSystemTools::ConvertToOutputPath(path);
    return ret;
    }
  ret = cmSystemTools::ConvertToOutputPath(ret.c_str());
  return ret;
}


// convert a command to a short path if it has spaces
// this separates the arguments from the command and puts
// them back together
std::string cmLocalNMakeMakefileGenerator::ShortPathCommand(const char* command)
{
  if (!command)
    {
    return "";
    }
  if(!strchr(command, ' '))
    {
    return command;
    }
  cmRegularExpression reg("^\"([^\"]*)\"(.*)");
  if(reg.find(command))
    {
    std::string c = reg.match(1);
    cmRegularExpression removeIntDir("(.*)(/|\\\\)\\$\\(IntDir\\)(.*)");
    if(removeIntDir.find(c))
      {
	c = removeIntDir.match(1) + removeIntDir.match(3);
      }
    std::string unixPath = c;
    // since the command may already be a windows path, convert it
    // to unix so we can use SplitProgramPath on it.
    cmSystemTools::ConvertToUnixSlashes(unixPath);
    std::string path, file;
    cmSystemTools::SplitProgramPath(unixPath.c_str(), path, file);
    // do a short path on the directory, because ShortPath will
    // not work for files that do not exist
    path = this->ShortPath(path.c_str());
    // now put the two back together
    path += "\\";
    path += file;
    std::string ret = path;
    std::string args = reg.match(2);
    ret += args;
    return ret;
    }
  return command;
}
  
void cmLocalNMakeMakefileGenerator::OutputMakeVariables(std::ostream& fout)
{
  fout << "# NMake Makefile generated by cmake\n";
  const char* variables = 
    "# general variables used in the makefile\n"
    "\n"
    "# Path to cmake\n"
    "MAKESILENT                             = /nologo\n"
    "CMAKE_STANDARD_WINDOWS_LIBRARIES       = @CMAKE_STANDARD_WINDOWS_LIBRARIES@\n"
    "CMAKE_C_FLAGS                          = @CMAKE_C_FLAGS@ @BUILD_FLAGS@ -DWIN32\n"
    "CMAKE_C_LINK_EXECUTABLE_FLAG           = @CMAKE_C_LINK_EXECUTABLE_FLAG@\n"
    "CMAKE_CXX_FLAGS                        = @CMAKE_CXX_FLAGS@ -DWIN32 @BUILD_FLAGS@\n"
    "CMAKE_LINKER_FLAGS                     = @CMAKE_LINKER_FLAGS@ @LINKER_BUILD_FLAGS@\n"
    "CMAKE_LINKER_SHARED_LIBRARY_FLAG       = @CMAKE_LINKER_SHARED_LIBRARY_FLAG@\n"
    "CMAKE_LIBRARY_MANAGER_FLAGS            = @CMAKE_LIBRARY_MANAGER_FLAGS@\n"
    "CMAKE_OBJECT_FILE_SUFFIX               = @CMAKE_OBJECT_FILE_SUFFIX@\n"
    "CMAKE_EXECUTABLE_SUFFIX                = @CMAKE_EXECUTABLE_SUFFIX@\n"
    "CMAKE_STATICLIB_SUFFIX                 = @CMAKE_STATICLIB_SUFFIX@\n"
    "CMAKE_SHLIB_SUFFIX                     = @CMAKE_SHLIB_SUFFIX@\n"
    "!IF \"$(OS)\" == \"Windows_NT\"\n"
    "NULL=\n"
    "!ELSE \n"
    "NULL=nul\n"
    "!ENDIF \n";

  std::string buildType = "CMAKE_CXX_FLAGS_";
  buildType +=  m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
  buildType = cmSystemTools::UpperCase(buildType);
  m_Makefile->AddDefinition("BUILD_FLAGS",
                            m_Makefile->GetDefinition(
                              buildType.c_str()));

  buildType = "CMAKE_LINKER_FLAGS_";
  buildType +=  m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
  buildType = cmSystemTools::UpperCase(buildType);
  m_Makefile->AddDefinition("LINKER_BUILD_FLAGS",
                            m_Makefile->GetDefinition(
                              buildType.c_str()));

  std::string replaceVars = variables;
  m_Makefile->ExpandVariablesInString(replaceVars);
  fout << replaceVars.c_str();
  std::string ccompiler = m_Makefile->GetDefinition("CMAKE_C_COMPILER");
  fout << "CMAKE_C_COMPILER                       = " 
       << this->ShortPath(ccompiler.c_str()) << "\n";

  std::string cxxcompiler = m_Makefile->GetDefinition("CMAKE_CXX_COMPILER");
  fout << "CMAKE_CXX_COMPILER                     = " 
       << this->ShortPath(cxxcompiler.c_str()) << "\n";

  std::string linker = m_Makefile->GetDefinition("CMAKE_LINKER");
  fout << "CMAKE_LINKER                           = " << 
    this->ShortPath(linker.c_str()) << "\n";

  std::string lib_manager = m_Makefile->GetDefinition("CMAKE_LIBRARY_MANAGER");
  fout << "CMAKE_LIBRARY_MANAGER                  = " 
       << this->ShortPath(lib_manager.c_str()) << "\n";

  std::string cmakecommand = m_Makefile->GetDefinition("CMAKE_COMMAND");
  fout << "CMAKE_COMMAND                          = "
       << this->ShortPath(cmakecommand.c_str()) << "\n";
  fout << "RM = " << this->ShortPath(cmakecommand.c_str()) << " -E remove -f\n";

  if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
    {
    fout << "CMAKE_EDIT_COMMAND = "
         << this->ShortPath(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
         << "\n";
    }

  fout << "CMAKE_CURRENT_SOURCE                   = " 
       << this->ShortPath(m_Makefile->GetStartDirectory() )
       << "\n";
  fout << "CMAKE_CURRENT_BINARY                   = " 
       << this->ShortPath(m_Makefile->GetStartOutputDirectory())
       << "\n";
  fout << "CMAKE_SOURCE_DIR                       = " 
       << this->ShortPath(m_Makefile->GetHomeDirectory()) << "\n";
  fout << "CMAKE_BINARY_DIR                       = " 
       << this->ShortPath(m_Makefile->GetHomeOutputDirectory() )
       << "\n";

  // Output Include paths
  fout << "INCLUDE_FLAGS                          = ";
  std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
  std::vector<std::string>::iterator i;
  fout << "-I" << 
    cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory()) << " ";
  for(i = includes.begin(); i != includes.end(); ++i)
    {
    std::string include = *i;
    // Don't output a -I for the standard include path "/usr/include".
    // This can cause problems with certain standard library
    // implementations because the wrong headers may be found first.
    fout << "-I" << cmSystemTools::ConvertToOutputPath(i->c_str()).c_str() << " ";
    } 

  fout << m_Makefile->GetDefineFlags();
  fout << "\n\n";
}


void cmLocalNMakeMakefileGenerator::BuildInSubDirectory(std::ostream& fout,
                                                   const char* directory,
                                                   const char* target1,
                                                   const char* target2,
                                                   bool silent)
{
  if(target1)
    {
    std::string dir = cmSystemTools::ConvertToOutputPath(directory);
    fout << "\tif not exist \"" << dir << "\\$(NULL)\""
         << " " 
         << "$(MAKE) $(MAKESILENT) rebuild_cache\n";
    if (!silent) 
      {
      fout << "\techo " << directory << ": building " << target1 << "\n";
      }
    fout << "\tcd " << dir << "\n"
         << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) " << target1 << "\n";
    }
  if(target2)
    {
    if (!silent) 
      {
      fout << "\techo " << directory << ": building " << target2 << "\n";
      }
    fout << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) " << target2 << "\n";
    }
  std::string currentDir = m_Makefile->GetCurrentOutputDirectory();
  fout << "\tcd " << cmSystemTools::ConvertToOutputPath(currentDir.c_str()) << "\n\n";
}




// This needs to be overriden because nmake requires commands to be quoted
// if the are full paths to the executable????

void cmLocalNMakeMakefileGenerator::OutputMakeRule(std::ostream& fout, 
                                              const char* comment,
                                              const char* target,
                                              const char* depends, 
                                              const char* command,
                                              const char* command2,
                                              const char* command3,
                                              const char* command4)
{
  std::string short_command;
  if (command)
    {
    short_command = ShortPathCommand(command);
    command = short_command.c_str();
    }

  std::string short_command2;
  if (command2)
    {
    short_command2 = ShortPathCommand(command2);
    command2 = short_command2.c_str();
    }

  std::string short_command3;
  if (command3)
    {
    short_command3 = ShortPathCommand(command3);
    command3 = short_command3.c_str();
    }

  std::string short_command4;
  if (command4)
    {
    short_command4 = ShortPathCommand(command4);
    command4 = short_command4.c_str();
    }

  cmLocalUnixMakefileGenerator::OutputMakeRule(fout, comment, 
                                               target, depends, 
                                               command, command2, 
                                               command3, command4);
  return;
}

void 
cmLocalNMakeMakefileGenerator::
OutputBuildObjectFromSource(std::ostream& fout,
                            const char* shortName,
                            const cmSourceFile& source,
                            const char* extraCompileFlags,
                            bool shared)
{ 
  // Header files shouldn't have build rules.
  if(source.GetPropertyAsBool("HEADER_FILE_ONLY"))
    {
    return;
    }

  std::string comment = "Build ";
  std::string objectFile = std::string(shortName) + 
    this->GetOutputExtension(source.GetSourceExtension().c_str());
  
  comment += objectFile + "  From ";
  comment += source.GetFullPath();
  std::string compileCommand;
  std::string ext = source.GetSourceExtension();
  if(ext == "c" )
    {
    compileCommand = "$(CMAKE_C_COMPILER) $(CMAKE_C_FLAGS) ";
    compileCommand += extraCompileFlags;
    if(shared)
      {
      compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
      }
    compileCommand += "$(INCLUDE_FLAGS) -c ";
    compileCommand += 
      cmSystemTools::ConvertToOutputPath(source.GetFullPath().c_str());

    // Need to get the definition here because this value might have
    // trailing space (since it is directly prepended to the filename)
    std::string output_object_file_flag = 
      m_Makefile->GetDefinition("CMAKE_C_OUTPUT_OBJECT_FILE_FLAG");
    m_Makefile->ExpandVariablesInString(output_object_file_flag);

    compileCommand += " " + output_object_file_flag;
    compileCommand += objectFile;
    }
  else if (ext == "rc")
    {
    compileCommand = "$(RC) $(INCLUDE_FLAGS) /fo\"";
    compileCommand += objectFile;
    compileCommand += "\" ";
    compileCommand += 
      cmSystemTools::ConvertToOutputPath(source.GetFullPath().c_str());
    }
  else if (ext == "def")
    {
    // no rule to output for this one
    return;
    }
  // assume c++ if not c rc or def
  else
    {
    
    compileCommand = "$(CMAKE_CXX_COMPILER) $(CMAKE_CXX_FLAGS) ";
    compileCommand += extraCompileFlags;
    if(shared)
      {
      compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
      }
    compileCommand += "$(INCLUDE_FLAGS) -c ";
    compileCommand += 
      cmSystemTools::ConvertToOutputPath(source.GetFullPath().c_str());

    // Need to get the definition here because this value might have
    // trailing space (since it is directly prepended to the filename)
    std::string output_object_file_flag = 
      m_Makefile->GetDefinition("CMAKE_C_OUTPUT_OBJECT_FILE_FLAG");
    m_Makefile->ExpandVariablesInString(output_object_file_flag);

    compileCommand += " " + output_object_file_flag;
    compileCommand += objectFile;
    }

  this->OutputMakeRule(fout,
                       comment.c_str(),
                       objectFile.c_str(),
                       cmSystemTools::ConvertToOutputPath(
                         source.GetFullPath().c_str()).c_str(),
                       compileCommand.c_str());
}

void cmLocalNMakeMakefileGenerator::OutputSharedLibraryRule(std::ostream& fout, 
                                                       const char* name,
                                                       const cmTarget &t)
{
  std::string target = m_LibraryOutputPath + name + m_SharedLibraryExtension;
  std::string depend = "$(";
  depend += this->CreateMakeVariable(name, "_SRC_OBJS");
  depend += ") $(" + this->CreateMakeVariable(name, "_DEPEND_LIBS") + ")";

  // Need to get the definition here because this value might have
  // trailing space (since it is directly prepended to the filename)
  std::string linker_output_file_flag = 
    m_Makefile->GetDefinition("CMAKE_LINKER_OUTPUT_FILE_FLAG");
  m_Makefile->ExpandVariablesInString(linker_output_file_flag);

  std::string command = "$(CMAKE_LINKER) $(CMAKE_LINKER_SHARED_LIBRARY_FLAG)";

  bool hide_param = m_Makefile->IsOn("CMAKE_LINKER_HIDE_PARAMETERS");
  if (hide_param)
    {
    command += " @<<\n\t";
    }

  command += " $(CMAKE_LINKER_FLAGS) " + linker_output_file_flag;

  std::string dllpath = m_LibraryOutputPath +  std::string(name) + m_SharedLibraryExtension;
  command += cmSystemTools::ConvertToOutputPath(dllpath.c_str());

  command += " $(" + this->CreateMakeVariable(name, "_SRC_OBJS") + ") ";

  cmStringStream linklibs;
  this->OutputLinkLibraries(linklibs, name, t);
  command += linklibs.str();

  const std::vector<cmSourceFile*>& sources = t.GetSourceFiles();
  for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
      i != sources.end(); ++i)
    {
    if((*i)->GetSourceExtension() == "def")
      {
      command += "/DEF:";
      command += (*i)->GetFullPath();
      }
    }

  command += "\n";
  if (hide_param)
    {
    command += "<<\n";
    }

  std::string customCommands = this->CreateTargetRules(t, name);
  const char* cc = 0;
  if(customCommands.size() > 0)
    {
    cc = customCommands.c_str();
    }
  this->OutputMakeRule(fout, "rules for a shared library",
                       target.c_str(),
                       depend.c_str(),
                       command.c_str(), cc);
}

void cmLocalNMakeMakefileGenerator::OutputModuleLibraryRule(std::ostream& fout, 
                                                       const char* name, 
                                                       const cmTarget &target)
{
  this->OutputSharedLibraryRule(fout, name, target);
}

void cmLocalNMakeMakefileGenerator::OutputStaticLibraryRule(std::ostream& fout, 
                                                       const char* name,
                                                       const cmTarget &t)
{
  std::string target = m_LibraryOutputPath + std::string(name) + m_StaticLibraryExtension;
  std::string depend = "$(";
  depend += this->CreateMakeVariable(name, "_SRC_OBJS") + ") ";

  // Need to get the definition here because this value might have
  // trailing space (since it is directly prepended to the filename)
  std::string library_manager_output_file_flag = 
    m_Makefile->GetDefinition("CMAKE_LIBRARY_MANAGER_OUTPUT_FILE_FLAG");
  m_Makefile->ExpandVariablesInString(library_manager_output_file_flag);

  std::string command = "$(CMAKE_LIBRARY_MANAGER) $(CMAKE_LIBRARY_MANAGER_FLAGS) @<<\n\t " + library_manager_output_file_flag;

  std::string libpath = m_LibraryOutputPath + std::string(name) + m_StaticLibraryExtension;
  command += cmSystemTools::ConvertToOutputPath(libpath.c_str());

  command += " $(";
  command += this->CreateMakeVariable(name, "_SRC_OBJS") + ")";
  command += "\n<<\n";

  std::string comment = "rule to build static library: ";
  comment += name;

  std::string customCommands = this->CreateTargetRules(t, name);
  const char* cc = 0;
  if(customCommands.size() > 0)
    {
    cc = customCommands.c_str();
    }
  this->OutputMakeRule(fout,
                       comment.c_str(),
                       target.c_str(),
                       depend.c_str(),
                       command.c_str(), cc);
}

void cmLocalNMakeMakefileGenerator::OutputExecutableRule(std::ostream& fout,
                                                    const char* name,
                                                    const cmTarget &t)
{
  std::string target = m_ExecutableOutputPath + name;
  target += m_ExecutableExtension;
  std::string depend = "$(";
  depend += this->CreateMakeVariable(name, "_SRC_OBJS") + ") $(" + 
    this->CreateMakeVariable(name, "_DEPEND_LIBS") +  ")";
  std::string command;
  if(t.HasCxx())
    {
    command = "$(CMAKE_CXX_COMPILER) $(CMAKE_CXX_FLAGS) ";
    }
  else
    {
    command = "${CMAKE_C_COMPILER} $(CMAKE_C_FLAGS) ";
    }
  bool hide_param = m_Makefile->IsOn("CMAKE_LINKER_HIDE_PARAMETERS");
  if (hide_param)
    {
    command += " @<<\n\t";
    }

  command += "$(" + this->CreateMakeVariable(name, "_SRC_OBJS") + ") ";
  std::string path = m_ExecutableOutputPath + name + m_ExecutableExtension;

  // Need to get the definition here because this value might have
  // trailing space (since it is directly prepended to the filename)
  std::string output_executable_file_flag = 
    m_Makefile->GetDefinition("CMAKE_C_OUTPUT_EXECUTABLE_FILE_FLAG");
  m_Makefile->ExpandVariablesInString(output_executable_file_flag);

  command += " " + output_executable_file_flag + 
    cmSystemTools::ConvertToOutputPath(path.c_str());

  command += " $(CMAKE_C_LINK_EXECUTABLE_FLAG) $(CMAKE_LINKER_FLAGS) ";
  if(t.GetType() == cmTarget::WIN32_EXECUTABLE)
    {
    command +=  " /subsystem:windows ";
    }
  
  cmStringStream linklibs;
  this->OutputLinkLibraries(linklibs, 0, t);
  command += linklibs.str();

  std::string comment = "rule to build executable: ";
  comment += name;

  std::string customCommands = this->CreateTargetRules(t, name);
  const char* cc = 0;
  if(customCommands.size() > 0)
    {
    cc = customCommands.c_str();
    } 
  if (hide_param)
    {
    command += "\n";
    command += "<<\n";
    }
  this->OutputMakeRule(fout, 
                       comment.c_str(),
                       target.c_str(),
                       depend.c_str(),
                       command.c_str(), cc);
}

  
void cmLocalNMakeMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
                                                   const char* targetLibrary,
                                                   const cmTarget &tgt)
{
  // Try to emit each search path once
  std::set<std::string> emitted;

  // Embed runtime search paths if possible and if required.
  // collect all the flags needed for linking libraries
  // Do not try if there is no library path option (it is set to -L or
  // -LIBPATH for some linker, but some others do not even support link
  // search path).
  std::string linkLibs;

  // Expand content because this value might have
  // trailing space (since it is directly prepended to the filename)
  std::string lib_path_opt = m_LibraryPathOption;
  m_Makefile->ExpandVariablesInString(lib_path_opt);
        
  if (lib_path_opt.size())
    {
    const std::vector<std::string>& libdirs = tgt.GetLinkDirectories();
    for(std::vector<std::string>::const_iterator libDir = libdirs.begin();
        libDir != libdirs.end(); ++libDir)
      { 
      std::string libpath = ShortPath(libDir->c_str());
      if(emitted.insert(libpath).second)
        {
        linkLibs += lib_path_opt;
        cmSystemTools::ConvertToOutputPath(libpath.c_str());
        linkLibs += libpath;
        linkLibs += " ";
        }
      }
    }

  std::string librariesLinked;
  const cmTarget::LinkLibraries& libs = tgt.GetLinkLibraries();
  for(cmTarget::LinkLibraries::const_iterator lib = libs.begin();
      lib != libs.end(); ++lib)
    {
    // Don't link the library against itself!
    if(targetLibrary && (lib->first == targetLibrary)) continue;

// ** should fix this later, it should check to see if this is 
// a debug build and add the library
// don't look at debug libraries
//    if (lib->second == cmTarget::DEBUG) continue;
    // skip zero size library entries, this may happen
    // if a variable expands to nothing.
    if (lib->first.size() == 0) continue;
    if(emitted.insert(lib->first).second)
      {
      std::string regexp = ".*\\";
      regexp += m_Makefile->GetDefinition("CMAKE_STATICLIB_SUFFIX");
      regexp += "$";
      cmRegularExpression reg(regexp.c_str());
      // if it ends in .lib, then it is a full path and should
      // be escaped, and does not need .lib added
      if(reg.find(lib->first))
	{
	librariesLinked +=  ShortPath(lib->first.c_str());
	librariesLinked += " ";
	}
      else
	{
        librariesLinked += m_LibraryLinkOption;
	librariesLinked += lib->first;
	librariesLinked += m_StaticLibraryExtension + " ";
	}
      }
    }
  linkLibs += librariesLinked;
  fout << linkLibs;
  fout << "$(CMAKE_STANDARD_WINDOWS_LIBRARIES) ";
}


std::string cmLocalNMakeMakefileGenerator::GetOutputExtension(const char* s)
{
  std::string sourceExtension = s;
  if(sourceExtension == "def")
    {
    return "";
    }
  if(sourceExtension == "ico" || sourceExtension == "rc2")
    {
    return "";
    }
  if(sourceExtension == "rc")
    {
    return ".res";
    }
  return m_ObjectFileExtension;
}


void cmLocalNMakeMakefileGenerator::OutputIncludeMakefile(std::ostream& fout,
                                                     const char* file)
{
  fout << "!include " << file << "\n";
}

bool cmLocalNMakeMakefileGenerator::SamePath(const char* path1, const char* path2)
{
  // first check to see if they are the same anyway
  if (strcmp(path1, path2) == 0)
    {
    return true;
    }
  // next short path and lower case both of them for the compare
  return 
    cmSystemTools::LowerCase(ShortPath(path1)) ==
    cmSystemTools::LowerCase(ShortPath(path2));
}

void cmLocalNMakeMakefileGenerator::OutputBuildTargetInDir(std::ostream& fout,
                                                      const char* path,
                                                      const char* library,
                                                      const char* fullpath,
                                                      const char* libOutPath)
{
  const char* makeTarget = library;
  std::string currentDir = 
    cmSystemTools::ConvertToOutputPath(m_Makefile->GetCurrentOutputDirectory());
  std::string wpath = cmSystemTools::ConvertToOutputPath(path);
  std::string wfullpath = cmSystemTools::ConvertToOutputPath(fullpath);
  if(libOutPath && strcmp( libOutPath, "" ) != 0)
    {
    makeTarget = wfullpath.c_str();
    }
  fout << wfullpath
       << ":\n\tcd " << wpath  << "\n"
       << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) cmake.depends\n"
       << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) cmake.check_depends\n"
       << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) -f cmake.check_depends\n"
       << "\t$(MAKE) $(MAKESILENT) " << makeTarget
       << "\n\tcd " << currentDir << "\n";
}

std::string cmLocalNMakeMakefileGenerator::CreateMakeVariable(const char* s, const char* s2)
{
  std::string ret=  std::string(s) + std::string(s2);
  cmSystemTools::ReplaceString(ret, "-", "_");
  return ret;
}

std::string cmLocalNMakeMakefileGenerator::LowerCasePath(const char* path)
{
  return cmSystemTools::LowerCase(path);
}