/*============================================================================
  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 "cmGlobalGenerator.h"
#include "cmLocalVisualStudio6Generator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmSourceFile.h"
#include "cmGeneratorTarget.h"
#include "cmCustomCommandGenerator.h"
#include "cmake.h"

#include "cmComputeLinkInformation.h"

#include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.hxx>

cmLocalVisualStudio6Generator
::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf):
  cmLocalVisualStudioGenerator(gg, mf)
{
}

cmLocalVisualStudio6Generator::~cmLocalVisualStudio6Generator()
{
}

//----------------------------------------------------------------------------
// Helper class to write build events.
class cmLocalVisualStudio6Generator::EventWriter
{
public:
  EventWriter(cmLocalVisualStudio6Generator* lg,
              const std::string& config, std::string& code):
    LG(lg), Config(config), Code(code), First(true) {}
  void Start(const char* event)
    {
    this->First = true;
    this->Event = event;
    }
  void Finish()
    {
    this->Code += (this->First? "" : "\n");
    }
  void Write(std::vector<cmCustomCommand> const& ccs)
    {
    for(std::vector<cmCustomCommand>::const_iterator ci = ccs.begin();
        ci != ccs.end(); ++ci)
      {
      this->Write(*ci);
      }
    }
  void Write(cmCustomCommand const& cc)
    {
    cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
    if(this->First)
      {
      this->Code += this->Event + "_Cmds=";
      this->First = false;
      }
    else
      {
      this->Code += "\\\n\t";
      }
    this->Code += this->LG->ConstructScript(ccg, "\\\n\t");
    }
private:
  cmLocalVisualStudio6Generator* LG;
  std::string Config;
  std::string& Code;
  bool First;
  std::string Event;
};

void cmLocalVisualStudio6Generator::AddCMakeListsRules()
{
  std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
  for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
      l != tgts.end(); ++l)
    {
    if ((*l)->GetType() == cmState::INTERFACE_LIBRARY
        || (*l)->GetType() == cmState::GLOBAL_TARGET)
      {
      continue;
      }

    // Add a rule to regenerate the build system when the target
    // specification source changes.
    const char* suppRegenRule =
      this->Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
    if (!cmSystemTools::IsOn(suppRegenRule))
      {
      this->AddDSPBuildRule(*l);
      }
    }
}

void cmLocalVisualStudio6Generator::Generate()
{
  this->OutputDSPFile();
}

void cmLocalVisualStudio6Generator::OutputDSPFile()
{
  // If not an in source build, then create the output directory
  if(strcmp(this->GetCurrentBinaryDirectory(),
            this->GetSourceDirectory()) != 0)
    {
    if(!cmSystemTools::MakeDirectory
       (this->GetCurrentBinaryDirectory()))
      {
      cmSystemTools::Error("Error creating directory ",
                           this->GetCurrentBinaryDirectory());
      }
    }

  // Create the DSP or set of DSP's for libraries and executables

  std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
  for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
      l != tgts.end(); ++l)
    {
    switch((*l)->GetType())
      {
      case cmState::STATIC_LIBRARY:
      case cmState::OBJECT_LIBRARY:
        this->SetBuildType(STATIC_LIBRARY,
                           (*l)->GetName().c_str(), *l);
        break;
      case cmState::SHARED_LIBRARY:
      case cmState::MODULE_LIBRARY:
        this->SetBuildType(DLL,
                           (*l)->GetName().c_str(), *l);
        break;
      case cmState::EXECUTABLE:
        this->SetBuildType(EXECUTABLE,
                           (*l)->GetName().c_str(), *l);
        break;
      case cmState::UTILITY:
      case cmState::GLOBAL_TARGET:
        this->SetBuildType(UTILITY,
                           (*l)->GetName().c_str(), *l);
        break;
      case cmState::INTERFACE_LIBRARY:
        continue;
      default:
        cmSystemTools::Error("Bad target type: ", (*l)->GetName().c_str());
        break;
      }
    // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
    // so don't build a projectfile for it
    const char* path =
      (*l)->GetProperty("EXTERNAL_MSPROJECT");
    if(!path)
      {
      // check to see if the dsp is going into a sub-directory
      std::string::size_type pos = (*l)->GetName().rfind('/');
      if(pos != std::string::npos)
        {
        std::string dir = this->GetCurrentBinaryDirectory();
        dir += "/";
        dir += (*l)->GetName().substr(0, pos);
        if(!cmSystemTools::MakeDirectory(dir.c_str()))
          {
          cmSystemTools::Error("Error creating directory: ", dir.c_str());
          }
        }
      this->CreateSingleDSP((*l)->GetName().c_str(), *l);
      }
    }
}

// Utility function to make a valid VS6 *.dsp filename out
// of a CMake target name:
//
extern std::string GetVS6TargetName(const std::string& targetName);

void cmLocalVisualStudio6Generator::CreateSingleDSP(const std::string& lname,
                                                    cmGeneratorTarget* target)
{
  // add to the list of projects
  std::string pname = GetVS6TargetName(lname);

  // create the dsp.cmake file
  std::string fname;
  fname = this->GetCurrentBinaryDirectory();
  fname += "/";
  fname += pname;
  fname += ".dsp";
  // save the name of the real dsp file
  std::string realDSP = fname;
  fname += ".cmake";
  cmsys::ofstream fout(fname.c_str());
  if(!fout)
    {
    cmSystemTools::Error("Error Writing ", fname.c_str());
    cmSystemTools::ReportLastSystemError("");
    }
  this->WriteDSPFile(fout,pname.c_str(),target);
  fout.close();
  // if the dsp file has changed, then write it.
  cmSystemTools::CopyFileIfDifferent(fname.c_str(), realDSP.c_str());
}


void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmGeneratorTarget *tgt)
{
  std::string dspname = GetVS6TargetName(tgt->GetName());
  dspname += ".dsp.cmake";
  cmCustomCommandLine commandLine;
  commandLine.push_back(cmSystemTools::GetCMakeCommand());
  std::string makefileIn = this->GetCurrentSourceDirectory();
  makefileIn += "/";
  makefileIn += "CMakeLists.txt";
  if(!cmSystemTools::FileExists(makefileIn.c_str()))
    {
    return;
    }
  std::string comment = "Building Custom Rule ";
  comment += makefileIn;
  std::string args;
  args = "-H";
  args += this->GetSourceDirectory();
  commandLine.push_back(args);
  args = "-B";
  args += this->GetBinaryDirectory();
  commandLine.push_back(args);

  std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();

  cmCustomCommandLines commandLines;
  commandLines.push_back(commandLine);
  const char* no_working_directory = 0;
  this->Makefile->AddCustomCommandToOutput(dspname.c_str(), listFiles,
                                           makefileIn.c_str(), commandLines,
                                           comment.c_str(),
                                           no_working_directory, true);
  if(this->Makefile->GetSource(makefileIn.c_str()))
    {
    tgt->AddSource(makefileIn);
    }
  else
    {
    cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
    }
}


void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
                                                 const std::string& libName,
                                                 cmGeneratorTarget *target)
{
  // For utility targets need custom command since pre- and post-
  // build does not do anything in Visual Studio 6.  In order for the
  // rules to run in the correct order as custom commands, we need
  // special care for dependencies.  The first rule must depend on all
  // the dependencies of all the rules.  The later rules must each
  // depend only on the previous rule.
  if ((target->GetType() == cmState::UTILITY ||
      target->GetType() == cmState::GLOBAL_TARGET) &&
      (!target->GetPreBuildCommands().empty() ||
       !target->GetPostBuildCommands().empty()))
    {
    // Accumulate the dependencies of all the commands.
    std::vector<std::string> depends;
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target->GetPreBuildCommands().begin();
         cr != target->GetPreBuildCommands().end(); ++cr)
      {
      depends.insert(depends.end(),
                     cr->GetDepends().begin(), cr->GetDepends().end());
      }
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target->GetPostBuildCommands().begin();
         cr != target->GetPostBuildCommands().end(); ++cr)
      {
      depends.insert(depends.end(),
                     cr->GetDepends().begin(), cr->GetDepends().end());
      }

    // Add the pre- and post-build commands in order.
    int count = 1;
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target->GetPreBuildCommands().begin();
         cr != target->GetPreBuildCommands().end(); ++cr)
      {
      this->AddUtilityCommandHack(target, count++, depends, *cr);
      }
    for (std::vector<cmCustomCommand>::const_iterator cr =
           target->GetPostBuildCommands().begin();
         cr != target->GetPostBuildCommands().end(); ++cr)
      {
      this->AddUtilityCommandHack(target, count++, depends, *cr);
      }
    }

  // We may be modifying the source groups temporarily, so make a copy.
  std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();

  // get the classes from the source lists then add them to the groups
  std::vector<cmSourceFile*> classes;
  if (!target->GetConfigCommonSourceFiles(classes))
    {
    return;
    }

  // now all of the source files have been properly assigned to the target
  // now stick them into source groups using the reg expressions
  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
      i != classes.end(); i++)
    {
    if (!(*i)->GetObjectLibrary().empty())
      {
      continue;
      }

    // Add the file to the list of sources.
    std::string source = (*i)->GetFullPath();
    cmSourceGroup* sourceGroup =
      this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
    sourceGroup->AssignSource(*i);
    // while we are at it, if it is a .rule file then for visual studio 6 we
    // must generate it
    if ((*i)->GetPropertyAsBool("__CMAKE_RULE"))
      {
      if(!cmSystemTools::FileExists(source.c_str()))
        {
        cmSystemTools::ReplaceString(source, "$(IntDir)/", "");
        // Make sure the path exists for the file
        std::string path = cmSystemTools::GetFilenamePath(source);
        cmSystemTools::MakeDirectory(path.c_str());
#if defined(_WIN32) || defined(__CYGWIN__)
        cmsys::ofstream sourceFout(source.c_str(),
                           std::ios::binary | std::ios::out
                           | std::ios::trunc);
#else
        cmsys::ofstream sourceFout(source.c_str(),
                           std::ios::out | std::ios::trunc);
#endif
        if(sourceFout)
          {
          sourceFout.write("# generated from CMake",22);
          sourceFout.flush();
          sourceFout.close();
          }
        }
      }
    }

  // Write the DSP file's header.
  this->WriteDSPHeader(fout, libName, target, sourceGroups);


  // Loop through every source group.
  for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
      sg != sourceGroups.end(); ++sg)
    {
    this->WriteGroup(&(*sg), target, fout, libName);
    }

  // Write the DSP file's footer.
  this->WriteDSPFooter(fout);
}

void cmLocalVisualStudio6Generator
::WriteGroup(const cmSourceGroup *sg, cmGeneratorTarget* target,
             std::ostream &fout, const std::string& libName)
{
  const std::vector<const cmSourceFile *> &sourceFiles =
    sg->GetSourceFiles();
  // If the group is empty, don't write it at all.

  if(sourceFiles.empty() && sg->GetGroupChildren().empty())
    {
    return;
    }

  // If the group has a name, write the header.
  std::string name = sg->GetName();
  if(name != "")
    {
    this->WriteDSPBeginGroup(fout, name.c_str(), "");
    }

  // Loop through each source in the source group.
  for(std::vector<const cmSourceFile *>::const_iterator sf =
        sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
    {
    if (!(*sf)->GetObjectLibrary().empty())
      {
      continue;
      }

    std::string source = (*sf)->GetFullPath();
    const cmCustomCommand *command =
      (*sf)->GetCustomCommand();
    std::string compileFlags;
    std::vector<std::string> depends;
    std::string objectNameDir;
    if(target->HasExplicitObjectName(*sf))
      {
      objectNameDir =
          cmSystemTools::GetFilenamePath(target->GetObjectName(*sf));
      }

    // Add per-source file flags.
    if(const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"))
      {
      compileFlags += cflags;
      }

    const std::string& lang = this->GetSourceFileLanguage(*(*sf));
    if(lang == "CXX")
      {
      // force a C++ file type
      compileFlags += " /TP ";
      }
    else if(lang == "C")
      {
      // force to c file type
      compileFlags += " /TC ";
      }

    // Add per-source and per-configuration preprocessor definitions.
    std::map<std::string, std::string> cdmap;

      {
      std::set<std::string> targetCompileDefinitions;

      this->AppendDefines(targetCompileDefinitions,
                        (*sf)->GetProperty("COMPILE_DEFINITIONS"));
      this->JoinDefines(targetCompileDefinitions, compileFlags, lang);
      }

    if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_DEBUG"))
      {
      std::set<std::string> debugCompileDefinitions;
      this->AppendDefines(debugCompileDefinitions, cdefs);
      this->JoinDefines(debugCompileDefinitions, cdmap["DEBUG"], lang);
      }
    if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_RELEASE"))
      {
      std::set<std::string> releaseCompileDefinitions;
      this->AppendDefines(releaseCompileDefinitions, cdefs);
      this->JoinDefines(releaseCompileDefinitions, cdmap["RELEASE"], lang);
      }
    if(const char* cdefs =
       (*sf)->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"))
      {
      std::set<std::string> minsizerelCompileDefinitions;
      this->AppendDefines(minsizerelCompileDefinitions, cdefs);
      this->JoinDefines(minsizerelCompileDefinitions, cdmap["MINSIZEREL"],
                        lang);
      }
    if(const char* cdefs =
       (*sf)->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"))
      {
      std::set<std::string> relwithdebinfoCompileDefinitions;
      this->AppendDefines(relwithdebinfoCompileDefinitions, cdefs);
      this->JoinDefines(relwithdebinfoCompileDefinitions,
                        cdmap["RELWITHDEBINFO"], lang);
      }

    bool excludedFromBuild =
      (!lang.empty() && (*sf)->GetPropertyAsBool("HEADER_FILE_ONLY"));

    // Check for extra object-file dependencies.
    const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS");
    if(dependsValue)
      {
      cmSystemTools::ExpandListArgument(dependsValue, depends);
      }
    if (GetVS6TargetName(source) != libName ||
      target->GetType() == cmState::UTILITY ||
      target->GetType() == cmState::GLOBAL_TARGET)
      {
      fout << "# Begin Source File\n\n";

      // Tell MS-Dev what the source is.  If the compiler knows how to
      // build it, then it will.
      fout << "SOURCE=" <<
        this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n";
      if(!depends.empty())
        {
        // Write out the dependencies for the rule.
        fout << "USERDEP__HACK=";
        for(std::vector<std::string>::const_iterator d = depends.begin();
            d != depends.end(); ++d)
          {
          fout << "\\\n\t" <<
            this->ConvertToOutputFormat(d->c_str(), SHELL);
          }
        fout << "\n";
        }
      if (command)
        {
        const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
        this->WriteCustomRule(fout, source.c_str(), *command, flags);
        }
      else if(!compileFlags.empty() || !objectNameDir.empty() ||
              excludedFromBuild || !cdmap.empty())
        {
        for(std::vector<std::string>::iterator i
              = this->Configurations.begin();
            i != this->Configurations.end(); ++i)
          {
          // Strip the subdirectory name out of the configuration name.
          std::string config = this->GetConfigName(*i);
          if (i == this->Configurations.begin())
            {
            fout << "!IF  \"$(CFG)\" == " << i->c_str() << std::endl;
            }
          else
            {
            fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
            }
          if(excludedFromBuild)
            {
            fout << "# PROP Exclude_From_Build 1\n";
            }
          if(!compileFlags.empty())
            {
            fout << "\n# ADD CPP " << compileFlags << "\n\n";
            }
          std::map<std::string, std::string>::iterator cdi =
            cdmap.find(cmSystemTools::UpperCase(config));
          if(cdi != cdmap.end() && !cdi->second.empty())
            {
            fout << "\n# ADD CPP " << cdi->second << "\n\n";
            }
          if(!objectNameDir.empty())
            {
            // Setup an alternate object file directory.
            fout << "\n# PROP Intermediate_Dir \""
                 << config << "/" << objectNameDir << "\"\n\n";
            }
          }
        fout << "!ENDIF\n\n";
        }
      fout << "# End Source File\n";
      }
    }

  std::vector<cmSourceGroup> const& children  = sg->GetGroupChildren();

  for(unsigned int i=0;i<children.size();++i)
    {
    this->WriteGroup(&children[i], target, fout, libName);
    }




  // If the group has a name, write the footer.
  if(name != "")
    {
    this->WriteDSPEndGroup(fout);
    }

}


void
cmLocalVisualStudio6Generator
::AddUtilityCommandHack(cmGeneratorTarget *target, int count,
                        std::vector<std::string>& depends,
                        const cmCustomCommand& origCommand)
{
  // Create a fake output that forces the rule to run.
  char* output = new char[(strlen(this->GetCurrentBinaryDirectory())
                           + target->GetName().size() + 30)];
  sprintf(output,"%s/%s_force_%i", this->GetCurrentBinaryDirectory(),
          target->GetName().c_str(), count);
  const char* comment = origCommand.GetComment();
  if(!comment && origCommand.GetOutputs().empty())
    {
    comment = "<hack>";
    }

  // Add the rule with the given dependencies and commands.
  std::string no_main_dependency = "";
  if(cmSourceFile* outsf =
     this->Makefile->AddCustomCommandToOutput(
       output, depends, no_main_dependency,
       origCommand.GetCommandLines(), comment,
       origCommand.GetWorkingDirectory().c_str()))
    {
    target->AddSource(outsf->GetFullPath());
    }

  // Replace the dependencies with the output of this rule so that the
  // next rule added will run after this one.
  depends.clear();
  depends.push_back(output);

  // Free the fake output name.
  delete [] output;
}

void
cmLocalVisualStudio6Generator
::WriteCustomRule(std::ostream& fout,
                  const char* source,
                  const cmCustomCommand& command,
                  const char* flags)
{
  // Write the rule for each configuration.
  std::vector<std::string>::iterator i;
  for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
    {
    std::string config = this->GetConfigName(*i);
    cmCustomCommandGenerator ccg(command, config, this);
    std::string comment =
      this->ConstructComment(ccg, "Building Custom Rule $(InputPath)");
    if(comment == "<hack>")
      {
      comment = "";
      }

    std::string script =
      this->ConstructScript(ccg, "\\\n\t");

    if (i == this->Configurations.begin())
      {
      fout << "!IF  \"$(CFG)\" == " << i->c_str() << std::endl;
      }
    else
      {
      fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
      }
    if(flags)
      {
      fout << "\n# ADD CPP " << flags << "\n\n";
      }
    // Write out the dependencies for the rule.
    fout << "USERDEP__HACK=";
    for(std::vector<std::string>::const_iterator d =
          ccg.GetDepends().begin();
        d != ccg.GetDepends().end();
        ++d)
      {
      // Lookup the real name of the dependency in case it is a CMake target.
      std::string dep;
      if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
        {
        fout << "\\\n\t" <<
          this->ConvertToOutputFormat(dep.c_str(), SHELL);
        }
      }
    fout << "\n";

    fout << "# PROP Ignore_Default_Tool 1\n";
    fout << "# Begin Custom Build -";
    if(!comment.empty())
      {
      fout << " " << comment.c_str();
      }
    fout << "\n\n";
    if(ccg.GetOutputs().empty())
      {
      fout << source
           << "_force :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
      fout << script.c_str() << "\n\n";
      }
    else
      {
      for(std::vector<std::string>::const_iterator o =
          ccg.GetOutputs().begin();
          o != ccg.GetOutputs().end();
          ++o)
        {
        // Write a rule for every output generated by this command.
        fout << this->ConvertToOutputFormat(o->c_str(), SHELL)
             << " :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
        fout << script.c_str() << "\n\n";
        }
      }
    fout << "# End Custom Build\n\n";
    }

  fout << "!ENDIF\n\n";
}


void cmLocalVisualStudio6Generator::WriteDSPBeginGroup(std::ostream& fout,
                                                       const char* group,
                                                       const char* filter)
{
  fout << "# Begin Group \"" << group << "\"\n"
    "# PROP Default_Filter \"" << filter << "\"\n";
}


void cmLocalVisualStudio6Generator::WriteDSPEndGroup(std::ostream& fout)
{
  fout << "# End Group\n";
}




void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
                                                 const std::string& libName,
                                                 cmGeneratorTarget *target)
{
  std::string root= this->Makefile->GetRequiredDefinition("CMAKE_ROOT");
  const char *def=
    this->Makefile->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");

  if( def)
    {
    root = def;
    }
  else
    {
    root += "/Templates";
    }

  switch(b)
    {
    case WIN32_EXECUTABLE:
      break;
    case STATIC_LIBRARY:
      this->DSPHeaderTemplate = root;
      this->DSPHeaderTemplate += "/staticLibHeader.dsptemplate";
      this->DSPFooterTemplate = root;
      this->DSPFooterTemplate += "/staticLibFooter.dsptemplate";
      break;
    case DLL:
      this->DSPHeaderTemplate =  root;
      this->DSPHeaderTemplate += "/DLLHeader.dsptemplate";
      this->DSPFooterTemplate =  root;
      this->DSPFooterTemplate += "/DLLFooter.dsptemplate";
      break;
    case EXECUTABLE:
      if ( target->GetPropertyAsBool("WIN32_EXECUTABLE") )
        {
        this->DSPHeaderTemplate = root;
        this->DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
        this->DSPFooterTemplate = root;
        this->DSPFooterTemplate += "/EXEFooter.dsptemplate";
        }
      else
        {
        this->DSPHeaderTemplate = root;
        this->DSPHeaderTemplate += "/EXEHeader.dsptemplate";
        this->DSPFooterTemplate = root;
        this->DSPFooterTemplate += "/EXEFooter.dsptemplate";
        }
      break;
    case UTILITY:
      this->DSPHeaderTemplate = root;
      this->DSPHeaderTemplate += "/UtilityHeader.dsptemplate";
      this->DSPFooterTemplate = root;
      this->DSPFooterTemplate += "/UtilityFooter.dsptemplate";
      break;
    }

  // once the build type is set, determine what configurations are
  // possible
  cmsys::ifstream fin(this->DSPHeaderTemplate.c_str());

  cmsys::RegularExpression reg("# Name ");
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
    }

  // reset this->Configurations
  this->Configurations.erase(this->Configurations.begin(),
                             this->Configurations.end());

  // now add all the configurations possible
  std::string vs6name = GetVS6TargetName(libName);
  std::string line;
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", vs6name.c_str());
    if (reg.find(line))
      {
      this->Configurations.push_back(line.substr(reg.end()));
      }
    }
}

//----------------------------------------------------------------------------
cmsys::auto_ptr<cmCustomCommand>
cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmGeneratorTarget* target,
                                                    const std::string& config)
{
  cmsys::auto_ptr<cmCustomCommand> pcc;

  // VS6 forgets to create the output directory for archives if it
  // differs from the intermediate directory.
  if(target->GetType() != cmState::STATIC_LIBRARY) { return pcc; }

  std::string outDir = target->GetDirectory(config, false);

  // Add a pre-link event to create the directory.
  cmCustomCommandLine command;
  command.push_back(cmSystemTools::GetCMakeCommand());
  command.push_back("-E");
  command.push_back("make_directory");
  command.push_back(outDir);
  std::vector<std::string> no_output;
  std::vector<std::string> no_byproducts;
  std::vector<std::string> no_depends;
  cmCustomCommandLines commands;
  commands.push_back(command);
  pcc.reset(new cmCustomCommand(0, no_output, no_byproducts,
                                no_depends, commands, 0, 0));
  pcc->SetEscapeOldStyle(false);
  pcc->SetEscapeAllowMakeVars(true);
  return pcc;
}

// look for custom rules on a target and collect them together
std::string
cmLocalVisualStudio6Generator::CreateTargetRules(cmGeneratorTarget *target,
                                              const std::string& configName,
                                              const std::string& /* libName */)
{
  if (target->GetType() >= cmState::UTILITY )
    {
    return "";
    }

  std::string customRuleCode = "# Begin Special Build Tool\n";
  EventWriter event(this, configName, customRuleCode);

  // Write the pre-build and pre-link together (VS6 does not support both).
  event.Start("PreLink");
  event.Write(target->GetPreBuildCommands());
  event.Write(target->GetPreLinkCommands());
  cmsys::auto_ptr<cmCustomCommand> pcc(
    this->MaybeCreateImplibDir(target, configName, false));
  if(pcc.get())
    {
    event.Write(*pcc);
    }
  pcc = this->MaybeCreateOutputDir(target, configName);
  if(pcc.get())
    {
    event.Write(*pcc);
    }
  event.Finish();

  // Write the post-build rules.
  event.Start("PostBuild");
  event.Write(target->GetPostBuildCommands());
  event.Finish();

  customRuleCode += "# End Special Build Tool\n";
  return customRuleCode;
}


inline std::string removeQuotes(const std::string& s)
{
  if(s[0] == '\"' && s[s.size()-1] == '\"')
    {
    return s.substr(1, s.size()-2);
    }
  return s;
}


std::string
cmLocalVisualStudio6Generator::GetTargetIncludeOptions(
        cmGeneratorTarget *target,
                                                  const std::string& config)
{
  std::string includeOptions;

  // Setup /I and /LIBPATH options for the resulting DSP file.  VS 6
  // truncates long include paths so make it as short as possible if
  // the length threatens this problem.
  unsigned int maxIncludeLength = 3000;
  bool useShortPath = false;

  for(int j=0; j < 2; ++j)
    {
    std::vector<std::string> includes;
    this->GetIncludeDirectories(includes, target, "C", config);

    std::vector<std::string>::iterator i;
    for(i = includes.begin(); i != includes.end(); ++i)
      {
      std::string tmp =
        this->ConvertToOutputFormat(i->c_str(), SHELL);
      if(useShortPath)
        {
        cmSystemTools::GetShortPath(tmp.c_str(), tmp);
        }
      includeOptions +=  " /I ";

      // quote if not already quoted
      if (tmp[0] != '"')
        {
        includeOptions += "\"";
        includeOptions += tmp;
        includeOptions += "\"";
        }
      else
        {
        includeOptions += tmp;
        }
      }

    if(j == 0 && includeOptions.size() > maxIncludeLength)
      {
      includeOptions = "";
      useShortPath = true;
      }
    else
      {
      break;
      }
    }

  return includeOptions;
}


// Code in blocks surrounded by a test for this definition is needed
// only for compatibility with user project's replacement DSP
// templates.  The CMake templates no longer use them.
#define CM_USE_OLD_VS6

void cmLocalVisualStudio6Generator
::WriteDSPHeader(std::ostream& fout,
                 const std::string& libName, cmGeneratorTarget* target,
                 std::vector<cmSourceGroup> &)
{
  bool targetBuilds = (target->GetType() >= cmState::EXECUTABLE &&
                       target->GetType() <= cmState::MODULE_LIBRARY);
#ifdef CM_USE_OLD_VS6
  // Lookup the library and executable output directories.
  std::string libPath;
  if(this->Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
    {
    libPath = this->Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
    }
  std::string exePath;
  if(this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
    {
    exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
    }

  // Make sure there are trailing slashes.
  if(!libPath.empty())
    {
    if(libPath[libPath.size()-1] != '/')
      {
      libPath += "/";
      }
    }
  if(!exePath.empty())
    {
    if(exePath[exePath.size()-1] != '/')
      {
      exePath += "/";
      }
    }

  std::set<std::string> pathEmitted;

  // determine the link directories
  std::string libOptions;
  std::string libDebugOptions;
  std::string libOptimizedOptions;

  std::string libMultiLineOptions;
  std::string libMultiLineOptionsForDebug;
  std::string libMultiLineDebugOptions;
  std::string libMultiLineOptimizedOptions;

  if(!libPath.empty())
    {
    std::string lpath =
      this->ConvertToOutputFormat(libPath.c_str(), SHELL);
    if(lpath.empty())
      {
      lpath = ".";
      }
    std::string lpathIntDir = libPath + "$(INTDIR)";
    lpathIntDir =
      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
    if(pathEmitted.insert(lpath).second)
      {
      libOptions += " /LIBPATH:";
      libOptions += lpathIntDir;
      libOptions += " ";
      libOptions += " /LIBPATH:";
      libOptions += lpath;
      libOptions += " ";
      libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptions += lpathIntDir;
      libMultiLineOptions += " ";
      libMultiLineOptions += " /LIBPATH:";
      libMultiLineOptions += lpath;
      libMultiLineOptions += " \n";
      libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptionsForDebug += lpathIntDir;
      libMultiLineOptionsForDebug += " ";
      libMultiLineOptionsForDebug += " /LIBPATH:";
      libMultiLineOptionsForDebug += lpath;
      libMultiLineOptionsForDebug += " \n";
      }
    }
  if(!exePath.empty())
    {
    std::string lpath =
      this->ConvertToOutputFormat(exePath.c_str(), SHELL);
    if(lpath.empty())
      {
      lpath = ".";
      }
    std::string lpathIntDir = exePath + "$(INTDIR)";
    lpathIntDir =
      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);

    if(pathEmitted.insert(lpath).second)
      {
      libOptions += " /LIBPATH:";
      libOptions += lpathIntDir;
      libOptions += " ";
      libOptions += " /LIBPATH:";
      libOptions += lpath;
      libOptions += " ";
      libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptions += lpathIntDir;
      libMultiLineOptions += " ";
      libMultiLineOptions += " /LIBPATH:";
      libMultiLineOptions += lpath;
      libMultiLineOptions += " \n";
      libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptionsForDebug += lpathIntDir;
      libMultiLineOptionsForDebug += " ";
      libMultiLineOptionsForDebug += " /LIBPATH:";
      libMultiLineOptionsForDebug += lpath;
      libMultiLineOptionsForDebug += " \n";
      }
    }
  std::vector<std::string>::const_iterator i;
  const std::vector<std::string>& libdirs =
      target->GetLinkDirectories();
  for(i = libdirs.begin(); i != libdirs.end(); ++i)
    {
    std::string path = *i;
    if(path[path.size()-1] != '/')
      {
      path += "/";
      }
    std::string lpath =
      this->ConvertToOutputFormat(path.c_str(), SHELL);
    if(lpath.empty())
      {
      lpath = ".";
      }
    std::string lpathIntDir = path + "$(INTDIR)";
    lpathIntDir =
      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
    if(pathEmitted.insert(lpath).second)
      {
      libOptions += " /LIBPATH:";
      libOptions += lpathIntDir;
      libOptions += " ";
      libOptions += " /LIBPATH:";
      libOptions += lpath;
      libOptions += " ";

      libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptions += lpathIntDir;
      libMultiLineOptions += " ";
      libMultiLineOptions += " /LIBPATH:";
      libMultiLineOptions += lpath;
      libMultiLineOptions += " \n";
      libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
      libMultiLineOptionsForDebug += lpathIntDir;
      libMultiLineOptionsForDebug += " ";
      libMultiLineOptionsForDebug += " /LIBPATH:";
      libMultiLineOptionsForDebug += lpath;
      libMultiLineOptionsForDebug += " \n";
      }
    }
  // find link libraries
  const cmTarget::LinkLibraryVectorType& libs =
    target->Target->GetLinkLibrariesForVS6();
  cmTarget::LinkLibraryVectorType::const_iterator j;
  for(j = libs.begin(); j != libs.end(); ++j)
    {
    // add libraries to executables and dlls (but never include
    // a library in a library, bad recursion)
    // NEVER LINK STATIC LIBRARIES TO OTHER STATIC LIBRARIES
    if ((target->GetType() != cmState::SHARED_LIBRARY
         && target->GetType() != cmState::STATIC_LIBRARY
         && target->GetType() != cmState::MODULE_LIBRARY) ||
        (target->GetType()==cmState::SHARED_LIBRARY
         && libName != GetVS6TargetName(j->first)) ||
        (target->GetType()==cmState::MODULE_LIBRARY
         && libName != GetVS6TargetName(j->first)))
      {
      // Compute the proper name to use to link this library.
      std::string lib;
      std::string libDebug;
      cmGeneratorTarget* tgt =
          this->GlobalGenerator->FindGeneratorTarget(j->first.c_str());
      if(tgt)
        {
        lib = cmSystemTools::GetFilenameWithoutExtension
          (tgt->GetFullName().c_str());
        libDebug = cmSystemTools::GetFilenameWithoutExtension
          (tgt->GetFullName("Debug").c_str());
        lib += ".lib";
        libDebug += ".lib";
        }
      else
        {
        lib = j->first.c_str();
        libDebug = j->first.c_str();
        if(j->first.find(".lib") == std::string::npos)
          {
          lib += ".lib";
          libDebug += ".lib";
          }
        }
      lib = this->ConvertToOutputFormat(lib.c_str(), SHELL);
      libDebug =
        this->ConvertToOutputFormat(libDebug.c_str(), SHELL);

      if (j->second == GENERAL_LibraryType)
        {
        libOptions += " ";
        libOptions += lib;
        libMultiLineOptions += "# ADD LINK32 ";
        libMultiLineOptions +=  lib;
        libMultiLineOptions += "\n";
        libMultiLineOptionsForDebug += "# ADD LINK32 ";
        libMultiLineOptionsForDebug +=  libDebug;
        libMultiLineOptionsForDebug += "\n";
        }
      if (j->second == DEBUG_LibraryType)
        {
        libDebugOptions += " ";
        libDebugOptions += lib;

        libMultiLineDebugOptions += "# ADD LINK32 ";
        libMultiLineDebugOptions += libDebug;
        libMultiLineDebugOptions += "\n";
        }
      if (j->second == OPTIMIZED_LibraryType)
        {
        libOptimizedOptions += " ";
        libOptimizedOptions += lib;

        libMultiLineOptimizedOptions += "# ADD LINK32 ";
        libMultiLineOptimizedOptions += lib;
        libMultiLineOptimizedOptions += "\n";
        }
      }
    }
#endif

  // Get include options for this target.
  std::string includeOptionsDebug = this->GetTargetIncludeOptions(target,
                                                                  "DEBUG");
  std::string includeOptionsRelease = this->GetTargetIncludeOptions(target,
                                                                  "RELEASE");
  std::string includeOptionsRelWithDebInfo = this->GetTargetIncludeOptions(
                                                            target,
                                                            "RELWITHDEBINFO");
  std::string includeOptionsMinSizeRel = this->GetTargetIncludeOptions(target,
                                                                "MINSIZEREL");

  // Get extra linker options for this target type.
  std::string extraLinkOptions;
  std::string extraLinkOptionsDebug;
  std::string extraLinkOptionsRelease;
  std::string extraLinkOptionsMinSizeRel;
  std::string extraLinkOptionsRelWithDebInfo;
  if(target->GetType() == cmState::EXECUTABLE)
    {
    extraLinkOptions = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS");
    extraLinkOptionsDebug = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_DEBUG");
    extraLinkOptionsRelease = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_RELEASE");
    extraLinkOptionsMinSizeRel = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_MINSIZEREL");
    extraLinkOptionsRelWithDebInfo = this->Makefile->
      GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO");
    }
  if(target->GetType() == cmState::SHARED_LIBRARY)
    {
    extraLinkOptions = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS");
    extraLinkOptionsDebug = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_DEBUG");
    extraLinkOptionsRelease = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_RELEASE");
    extraLinkOptionsMinSizeRel = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL");
    extraLinkOptionsRelWithDebInfo = this->Makefile->
      GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO");
    }
  if(target->GetType() == cmState::MODULE_LIBRARY)
    {
    extraLinkOptions = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS");
    extraLinkOptionsDebug = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_DEBUG");
    extraLinkOptionsRelease = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_RELEASE");
    extraLinkOptionsMinSizeRel = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL");
    extraLinkOptionsRelWithDebInfo = this->Makefile->
      GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO");
    }

  // Get extra linker options for this target.
  if(const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"))
    {
    extraLinkOptions += " ";
    extraLinkOptions += targetLinkFlags;
    }

  if(const char* targetLinkFlags = target->GetProperty("LINK_FLAGS_DEBUG"))
    {
    extraLinkOptionsDebug += " ";
    extraLinkOptionsDebug += targetLinkFlags;
    }

  if(const char* targetLinkFlags = target->GetProperty("LINK_FLAGS_RELEASE"))
    {
    extraLinkOptionsRelease += " ";
    extraLinkOptionsRelease += targetLinkFlags;
    }

  if(const char* targetLinkFlags =
     target->GetProperty("LINK_FLAGS_MINSIZEREL"))
    {
    extraLinkOptionsMinSizeRel += " ";
    extraLinkOptionsMinSizeRel += targetLinkFlags;
    }

  if(const char* targetLinkFlags =
     target->GetProperty("LINK_FLAGS_RELWITHDEBINFO"))
    {
    extraLinkOptionsRelWithDebInfo += " ";
    extraLinkOptionsRelWithDebInfo += targetLinkFlags;
    }

  // Get standard libraries for this language.
  if(targetBuilds)
    {
    // Get the language to use for linking.
    std::vector<std::string> configs;
    target->Target->GetMakefile()->GetConfigurations(configs);
    std::vector<std::string>::const_iterator it = configs.begin();
    const std::string& linkLanguage = target->GetLinkerLanguage(*it);
    for ( ; it != configs.end(); ++it)
      {
      const std::string& configLinkLanguage = target->GetLinkerLanguage(*it);
      if (configLinkLanguage != linkLanguage)
        {
        cmSystemTools::Error
          ("Linker language must not vary by configuration for target: ",
          target->GetName().c_str());
        }
      }
    if(linkLanguage.empty())
      {
      cmSystemTools::Error
        ("CMake can not determine linker language for target: ",
         target->GetName().c_str());
      return;
      }

    // Compute the variable name to lookup standard libraries for this
    // language.
    std::string standardLibsVar = "CMAKE_";
    standardLibsVar += linkLanguage;
    standardLibsVar += "_STANDARD_LIBRARIES";

    // Add standard libraries.
    if(const char* stdLibs =
       this->Makefile->GetDefinition(standardLibsVar.c_str()))
      {
      extraLinkOptions += " ";
      extraLinkOptions += stdLibs;
      }
    }

  // Compute version number information.
  std::string targetVersionFlag;
  if(target->GetType() == cmState::EXECUTABLE ||
     target->GetType() == cmState::SHARED_LIBRARY ||
     target->GetType() == cmState::MODULE_LIBRARY)
    {
    int major;
    int minor;
    target->GetTargetVersion(major, minor);
    std::ostringstream targetVersionStream;
    targetVersionStream << "/version:" << major << "." << minor;
    targetVersionFlag = targetVersionStream.str();
    }

  // Compute the real name of the target.
  std::string outputName =
    "(OUTPUT_NAME is for libraries and executables only)";
  std::string outputNameDebug = outputName;
  std::string outputNameRelease = outputName;
  std::string outputNameMinSizeRel = outputName;
  std::string outputNameRelWithDebInfo = outputName;
  if(target->GetType() == cmState::EXECUTABLE ||
     target->GetType() == cmState::STATIC_LIBRARY ||
     target->GetType() == cmState::SHARED_LIBRARY ||
     target->GetType() == cmState::MODULE_LIBRARY)
    {
    outputName = target->GetFullName();
    outputNameDebug = target->GetFullName("Debug");
    outputNameRelease = target->GetFullName("Release");
    outputNameMinSizeRel = target->GetFullName("MinSizeRel");
    outputNameRelWithDebInfo = target->GetFullName("RelWithDebInfo");
    }
  else if(target->GetType() == cmState::OBJECT_LIBRARY)
    {
    outputName = target->GetName();
    outputName += ".lib";
    outputNameDebug = outputName;
    outputNameRelease = outputName;
    outputNameMinSizeRel = outputName;
    outputNameRelWithDebInfo = outputName;
    }

  // Compute the output directory for the target.
  std::string outputDirOld;
  std::string outputDirDebug;
  std::string outputDirRelease;
  std::string outputDirMinSizeRel;
  std::string outputDirRelWithDebInfo;
  if(target->GetType() == cmState::EXECUTABLE ||
     target->GetType() == cmState::STATIC_LIBRARY ||
     target->GetType() == cmState::SHARED_LIBRARY ||
     target->GetType() == cmState::MODULE_LIBRARY)
    {
#ifdef CM_USE_OLD_VS6
    outputDirOld =
      removeQuotes(this->ConvertToOutputFormat
                   (target->GetDirectory().c_str(), SHELL));
#endif
    outputDirDebug =
        removeQuotes(this->ConvertToOutputFormat(
                       target->GetDirectory("Debug").c_str(), SHELL));
    outputDirRelease =
        removeQuotes(this->ConvertToOutputFormat(
                 target->GetDirectory("Release").c_str(), SHELL));
    outputDirMinSizeRel =
        removeQuotes(this->ConvertToOutputFormat(
                 target->GetDirectory("MinSizeRel").c_str(), SHELL));
    outputDirRelWithDebInfo =
        removeQuotes(this->ConvertToOutputFormat(
                 target->GetDirectory("RelWithDebInfo").c_str(), SHELL));
    }
  else if(target->GetType() == cmState::OBJECT_LIBRARY)
    {
    std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash();
    outputDirDebug = outputDir + "Debug";
    outputDirRelease = outputDir + "Release";
    outputDirMinSizeRel = outputDir + "MinSizeRel";
    outputDirRelWithDebInfo = outputDir + "RelWithDebInfo";
    }

  // Compute the proper link information for the target.
  std::string optionsDebug;
  std::string optionsRelease;
  std::string optionsMinSizeRel;
  std::string optionsRelWithDebInfo;
  if(target->GetType() == cmState::EXECUTABLE ||
     target->GetType() == cmState::SHARED_LIBRARY ||
     target->GetType() == cmState::MODULE_LIBRARY)
    {
    extraLinkOptionsDebug =
      extraLinkOptions + " " + extraLinkOptionsDebug;
    extraLinkOptionsRelease =
      extraLinkOptions + " " + extraLinkOptionsRelease;
    extraLinkOptionsMinSizeRel =
      extraLinkOptions + " " + extraLinkOptionsMinSizeRel;
    extraLinkOptionsRelWithDebInfo =
      extraLinkOptions + " " + extraLinkOptionsRelWithDebInfo;
    this->ComputeLinkOptions(target, "Debug", extraLinkOptionsDebug,
                             optionsDebug);
    this->ComputeLinkOptions(target, "Release", extraLinkOptionsRelease,
                             optionsRelease);
    this->ComputeLinkOptions(target, "MinSizeRel", extraLinkOptionsMinSizeRel,
                             optionsMinSizeRel);
    this->ComputeLinkOptions(target, "RelWithDebInfo",
                             extraLinkOptionsRelWithDebInfo,
                             optionsRelWithDebInfo);
    }

  // Compute the path of the import library.
  std::string targetImplibFlagDebug;
  std::string targetImplibFlagRelease;
  std::string targetImplibFlagMinSizeRel;
  std::string targetImplibFlagRelWithDebInfo;
  if(target->GetType() == cmState::SHARED_LIBRARY ||
     target->GetType() == cmState::MODULE_LIBRARY ||
     target->GetType() == cmState::EXECUTABLE)
    {
    std::string fullPathImpDebug = target->GetDirectory("Debug", true);
    std::string fullPathImpRelease = target->GetDirectory("Release", true);
    std::string fullPathImpMinSizeRel =
      target->GetDirectory("MinSizeRel", true);
    std::string fullPathImpRelWithDebInfo =
      target->GetDirectory("RelWithDebInfo", true);
    fullPathImpDebug += "/";
    fullPathImpRelease += "/";
    fullPathImpMinSizeRel += "/";
    fullPathImpRelWithDebInfo += "/";
    fullPathImpDebug += target->GetFullName("Debug", true);
    fullPathImpRelease += target->GetFullName("Release", true);
    fullPathImpMinSizeRel += target->GetFullName("MinSizeRel", true);
    fullPathImpRelWithDebInfo += target->GetFullName("RelWithDebInfo", true);

    targetImplibFlagDebug = "/implib:";
    targetImplibFlagRelease = "/implib:";
    targetImplibFlagMinSizeRel = "/implib:";
    targetImplibFlagRelWithDebInfo = "/implib:";
    targetImplibFlagDebug +=
      this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL);
    targetImplibFlagRelease +=
      this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL);
    targetImplibFlagMinSizeRel +=
      this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL);
    targetImplibFlagRelWithDebInfo +=
      this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL);
    }

#ifdef CM_USE_OLD_VS6
  // Compute link information for the target.
  if(!extraLinkOptions.empty())
    {
    libOptions += " ";
    libOptions += extraLinkOptions;
    libOptions += " ";
    libMultiLineOptions += "# ADD LINK32 ";
    libMultiLineOptions +=  extraLinkOptions;
    libMultiLineOptions += " \n";
    libMultiLineOptionsForDebug += "# ADD LINK32 ";
    libMultiLineOptionsForDebug +=  extraLinkOptions;
    libMultiLineOptionsForDebug += " \n";
    }
#endif

  // are there any custom rules on the target itself
  // only if the target is a lib or exe
  std::string customRuleCodeRelease
      = this->CreateTargetRules(target, "RELEASE",        libName);
  std::string customRuleCodeDebug
      = this->CreateTargetRules(target, "DEBUG",          libName);
  std::string customRuleCodeMinSizeRel
      = this->CreateTargetRules(target, "MINSIZEREL",     libName);
  std::string customRuleCodeRelWithDebInfo
      = this->CreateTargetRules(target, "RELWITHDEBINFO", libName);

  cmsys::ifstream fin(this->DSPHeaderTemplate.c_str());
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
    }
  std::string staticLibOptions;
  std::string staticLibOptionsDebug;
  std::string staticLibOptionsRelease;
  std::string staticLibOptionsMinSizeRel;
  std::string staticLibOptionsRelWithDebInfo;
  if(target->GetType() == cmState::STATIC_LIBRARY )
    {
    const char *libflagsGlobal =
      this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS");
    this->AppendFlags(staticLibOptions, libflagsGlobal);
    this->AppendFlags(staticLibOptionsDebug, libflagsGlobal);
    this->AppendFlags(staticLibOptionsRelease, libflagsGlobal);
    this->AppendFlags(staticLibOptionsMinSizeRel, libflagsGlobal);
    this->AppendFlags(staticLibOptionsRelWithDebInfo, libflagsGlobal);

    this->AppendFlags(staticLibOptionsDebug, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_DEBUG"));
    this->AppendFlags(staticLibOptionsRelease, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_RELEASE"));
    this->AppendFlags(staticLibOptionsMinSizeRel, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL"));
    this->AppendFlags(staticLibOptionsRelWithDebInfo, this->Makefile->
      GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO"));

    const char *libflags = target->GetProperty("STATIC_LIBRARY_FLAGS");
    this->AppendFlags(staticLibOptions, libflags);
    this->AppendFlags(staticLibOptionsDebug, libflags);
    this->AppendFlags(staticLibOptionsRelease, libflags);
    this->AppendFlags(staticLibOptionsMinSizeRel, libflags);
    this->AppendFlags(staticLibOptionsRelWithDebInfo, libflags);

    this->AppendFlags(staticLibOptionsDebug,
      target->GetProperty("STATIC_LIBRARY_FLAGS_DEBUG"));
    this->AppendFlags(staticLibOptionsRelease,
      target->GetProperty("STATIC_LIBRARY_FLAGS_RELEASE"));
    this->AppendFlags(staticLibOptionsMinSizeRel,
      target->GetProperty("STATIC_LIBRARY_FLAGS_MINSIZEREL"));
    this->AppendFlags(staticLibOptionsRelWithDebInfo,
      target->GetProperty("STATIC_LIBRARY_FLAGS_RELWITHDEBINFO"));

    std::string objects;
    this->OutputObjects(target, "LIB", objects);
    if(!objects.empty())
      {
      objects = "\n" + objects;
      staticLibOptionsDebug += objects;
      staticLibOptionsRelease += objects;
      staticLibOptionsMinSizeRel += objects;
      staticLibOptionsRelWithDebInfo += objects;
      }
    }

  // Add the export symbol definition for shared library objects.
  std::string exportSymbol;
  if(const char* exportMacro = target->GetExportMacro())
    {
    exportSymbol = exportMacro;
    }

  std::string line;
  std::string libnameExports;
  if(!exportSymbol.empty())
    {
    libnameExports = "/D \"";
    libnameExports += exportSymbol;
    libnameExports += "\"";
    }
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
    if(!mfcFlag)
      {
      mfcFlag = "0";
      }
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME_EXPORTS",
                                 libnameExports.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
                                 mfcFlag);
    if(target->GetType() == cmState::STATIC_LIBRARY ||
       target->GetType() == cmState::OBJECT_LIBRARY)
      {
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG",
                                   staticLibOptionsDebug.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELEASE",
                                   staticLibOptionsRelease.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_MINSIZEREL",
                                   staticLibOptionsMinSizeRel.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELWITHDEBINFO",
                                   staticLibOptionsRelWithDebInfo.c_str());
      cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS",
                                   staticLibOptions.c_str());
      }
    if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
      {
      cmSystemTools::ReplaceString(line, "/nologo", "");
      }

#ifdef CM_USE_OLD_VS6
    cmSystemTools::ReplaceString(line, "CM_LIBRARIES",
                                 libOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
                                 libDebugOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_OPTIMIZED_LIBRARIES",
                                 libOptimizedOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES_FOR_DEBUG",
                                 libMultiLineOptionsForDebug.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES",
                                 libMultiLineOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_DEBUG_LIBRARIES",
                                 libMultiLineDebugOptions.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES",
                                 libMultiLineOptimizedOptions.c_str());
#endif

    // Substitute the rules for custom command. When specifying just the
    // target name for the command the command can be different for
    // different configs
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELEASE",
                                 customRuleCodeRelease.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_DEBUG",
                                 customRuleCodeDebug.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_MINSIZEREL",
                                 customRuleCodeMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO",
                                 customRuleCodeRelWithDebInfo.c_str());

    // Substitute the real output name into the template.
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_DEBUG",
                                 outputNameDebug.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELEASE",
                                 outputNameRelease.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_MINSIZEREL",
                                 outputNameMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELWITHDEBINFO",
                                 outputNameRelWithDebInfo.c_str());
    cmSystemTools::ReplaceString(line, "OUTPUT_NAME", outputName.c_str());

    // Substitute the proper link information into the template.
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_DEBUG",
                                 optionsDebug.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELEASE",
                                 optionsRelease.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_MINSIZEREL",
                                 optionsMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELWITHDEBINFO",
                                 optionsRelWithDebInfo.c_str());

    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_DEBUG",
                                 includeOptionsDebug.c_str());
    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_RELEASE",
                                 includeOptionsRelease.c_str());
    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_MINSIZEREL",
                                 includeOptionsMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_RELWITHDEBINFO",
                                 includeOptionsRelWithDebInfo.c_str());

    cmSystemTools::ReplaceString(line, "TARGET_VERSION_FLAG",
                                 targetVersionFlag.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_DEBUG",
                                 targetImplibFlagDebug.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_RELEASE",
                                 targetImplibFlagRelease.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_MINSIZEREL",
                                 targetImplibFlagMinSizeRel.c_str());
    cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_RELWITHDEBINFO",
                                 targetImplibFlagRelWithDebInfo.c_str());

    std::string vs6name = GetVS6TargetName(libName);
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", vs6name.c_str());

#ifdef CM_USE_OLD_VS6
    // because LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH
    // are already quoted in the template file,
    // we need to remove the quotes here, we still need
    // to convert to output path for unix to win32 conversion
    cmSystemTools::ReplaceString
      (line, "LIBRARY_OUTPUT_PATH",
       removeQuotes(this->ConvertToOutputFormat
                    (libPath.c_str(), SHELL)).c_str());
    cmSystemTools::ReplaceString
      (line, "EXECUTABLE_OUTPUT_PATH",
       removeQuotes(this->ConvertToOutputFormat
                    (exePath.c_str(), SHELL)).c_str());
#endif

    if(targetBuilds || target->GetType() == cmState::OBJECT_LIBRARY)
      {
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG",
                                   outputDirDebug.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELEASE",
                                   outputDirRelease.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_MINSIZEREL",
                                   outputDirMinSizeRel.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELWITHDEBINFO",
                                   outputDirRelWithDebInfo.c_str());
      if(!outputDirOld.empty())
        {
        cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY",
                                     outputDirOld.c_str());
        }
      }

    cmSystemTools::ReplaceString(line,
                                 "EXTRA_DEFINES",
                                 this->Makefile->GetDefineFlags());
    const char* debugPostfix
      = this->Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
    cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX",
                                 debugPostfix?debugPostfix:"");
    if(target->GetType() >= cmState::EXECUTABLE &&
       target->GetType() <= cmState::OBJECT_LIBRARY)
      {
      // store flags for each configuration
      std::string flags = " ";
      std::string flagsRelease = " ";
      std::string flagsMinSizeRel = " ";
      std::string flagsDebug = " ";
      std::string flagsRelWithDebInfo = " ";
      std::vector<std::string> configs;
      target->Target->GetMakefile()->GetConfigurations(configs);
      std::vector<std::string>::const_iterator it = configs.begin();
      const std::string& linkLanguage = target->GetLinkerLanguage(*it);
      for ( ; it != configs.end(); ++it)
        {
        const std::string& configLinkLanguage = target->GetLinkerLanguage(*it);
        if (configLinkLanguage != linkLanguage)
          {
          cmSystemTools::Error
            ("Linker language must not vary by configuration for target: ",
            target->GetName().c_str());
          }
        }
      if(linkLanguage.empty())
        {
        cmSystemTools::Error
          ("CMake can not determine linker language for target: ",
           target->GetName().c_str());
        return;
        }
      // if CXX is on and the target contains cxx code then add the cxx flags
      std::string baseFlagVar = "CMAKE_";
      baseFlagVar += linkLanguage;
      baseFlagVar += "_FLAGS";
      flags = this->Makefile->GetSafeDefinition(baseFlagVar.c_str());

      std::string flagVar = baseFlagVar + "_RELEASE";
      flagsRelease = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" ";

      flagVar = baseFlagVar + "_MINSIZEREL";
      flagsMinSizeRel = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsMinSizeRel += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" ";

      flagVar = baseFlagVar + "_DEBUG";
      flagsDebug = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" ";

      flagVar = baseFlagVar + "_RELWITHDEBINFO";
      flagsRelWithDebInfo = this->Makefile->GetSafeDefinition(flagVar.c_str());
      flagsRelWithDebInfo += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" ";

      this->AddCompileOptions(flags, target, linkLanguage, "");
      this->AddCompileOptions(flagsDebug, target, linkLanguage, "Debug");
      this->AddCompileOptions(flagsRelease, target, linkLanguage, "Release");
      this->AddCompileOptions(flagsMinSizeRel, target, linkLanguage,
                              "MinSizeRel");
      this->AddCompileOptions(flagsRelWithDebInfo, target, linkLanguage,
                              "RelWithDebInfo");

      // if _UNICODE and _SBCS are not found, then add -D_MBCS
      std::string defs = this->Makefile->GetDefineFlags();
      if(flags.find("D_UNICODE") == flags.npos &&
         defs.find("D_UNICODE") == flags.npos &&
         flags.find("D_SBCS") == flags.npos &&
         defs.find("D_SBCS") == flags.npos)
        {
        flags += " /D \"_MBCS\"";
        }

      // Add per-target and per-configuration preprocessor definitions.
      std::set<std::string> definesSet;
      std::set<std::string> debugDefinesSet;
      std::set<std::string> releaseDefinesSet;
      std::set<std::string> minsizeDefinesSet;
      std::set<std::string> debugrelDefinesSet;

      this->AddCompileDefinitions(definesSet, target, "", linkLanguage);
      this->AddCompileDefinitions(debugDefinesSet, target,
                                  "DEBUG", linkLanguage);
      this->AddCompileDefinitions(releaseDefinesSet, target,
                                  "RELEASE", linkLanguage);
      this->AddCompileDefinitions(minsizeDefinesSet, target,
                                  "MINSIZEREL", linkLanguage);
      this->AddCompileDefinitions(debugrelDefinesSet, target,
                                  "RELWITHDEBINFO", linkLanguage);

      std::string defines = " ";
      std::string debugDefines = " ";
      std::string releaseDefines = " ";
      std::string minsizeDefines = " ";
      std::string debugrelDefines = " ";

      this->JoinDefines(definesSet, defines, "");
      this->JoinDefines(debugDefinesSet, debugDefines, "");
      this->JoinDefines(releaseDefinesSet, releaseDefines, "");
      this->JoinDefines(minsizeDefinesSet, minsizeDefines, "");
      this->JoinDefines(debugrelDefinesSet, debugrelDefines, "");

      flags += defines;
      flagsDebug += debugDefines;
      flagsRelease += releaseDefines;
      flagsMinSizeRel += minsizeDefines;
      flagsRelWithDebInfo += debugrelDefines;

      // The template files have CXX FLAGS in them, that need to be replaced.
      // There are not separate CXX and C template files, so we use the same
      // variable names.   The previous code sets up flags* variables to
      // contain the correct C or CXX flags
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL",
                                   flagsMinSizeRel.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
                                   flagsDebug.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
                                   flagsRelWithDebInfo.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE",
                                   flagsRelease.c_str());
      cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str());

      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL",
                                   minsizeDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG",
                                   debugDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO",
                                   debugrelDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE",
                                   releaseDefines.c_str());
      cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS",
                                   defines.c_str());
      }

    fout << line.c_str() << std::endl;
    }
}

void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout)
{
  cmsys::ifstream fin(this->DSPFooterTemplate.c_str());
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ",
                         this->DSPFooterTemplate.c_str());
    }
  std::string line;
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    fout << line << std::endl;
    }
}

//----------------------------------------------------------------------------
void cmLocalVisualStudio6Generator
::ComputeLinkOptions(cmGeneratorTarget *target,
                     const std::string& configName,
                     const std::string extraOptions,
                     std::string& options)
{
  // Compute the link information for this configuration.
  cmComputeLinkInformation* pcli = target->GetLinkInformation(configName);
  if(!pcli)
    {
    return;
    }
  cmComputeLinkInformation& cli = *pcli;
  typedef cmComputeLinkInformation::ItemVector ItemVector;
  ItemVector const& linkLibs = cli.GetItems();
  std::vector<std::string> const& linkDirs = cli.GetDirectories();

  this->OutputObjects(target, "LINK", options);

  // Build the link options code.
  for(std::vector<std::string>::const_iterator d = linkDirs.begin();
      d != linkDirs.end(); ++d)
    {
    std::string dir = *d;
    if(!dir.empty())
      {
      if(dir[dir.size()-1] != '/')
        {
        dir += "/";
        }
      dir += "$(IntDir)";
      options += "# ADD LINK32 /LIBPATH:";
      options += this->ConvertToOutputFormat(dir.c_str(), SHELL);
      options += " /LIBPATH:";
      options += this->ConvertToOutputFormat(d->c_str(), SHELL);
      options += "\n";
      }
    }
  for(ItemVector::const_iterator l = linkLibs.begin();
      l != linkLibs.end(); ++l)
    {
    options += "# ADD LINK32 ";
    if(l->IsPath)
      {
      options +=
        this->ConvertToOutputFormat(l->Value.c_str(), SHELL);
      }
    else if (!l->Target
        || l->Target->GetType() != cmState::INTERFACE_LIBRARY)
      {
      options += l->Value;
      }
    options += "\n";
    }

  // Add extra options if any.
  if(!extraOptions.empty())
    {
    options += "# ADD LINK32 ";
    options += extraOptions;
    options += "\n";
    }
}

//----------------------------------------------------------------------------
void cmLocalVisualStudio6Generator
::OutputObjects(cmGeneratorTarget* target, const char* tool,
                std::string& options)
{
  // VS 6 does not support per-config source locations so we
  // list object library content on the link line instead.
  std::vector<std::string> objs;
  target->UseObjectLibraries(objs, "");
  for(std::vector<std::string>::const_iterator
        oi = objs.begin(); oi != objs.end(); ++oi)
    {
    options += "# ADD ";
    options += tool;
    options += "32 ";
    options += this->ConvertToOutputFormat(oi->c_str(), SHELL);
    options += "\n";
    }
}

std::string
cmLocalVisualStudio6Generator
::GetTargetDirectory(cmGeneratorTarget const*) const
{
  // No per-target directory for this generator (yet).
  return "";
}

//----------------------------------------------------------------------------
std::string
cmLocalVisualStudio6Generator
::ComputeLongestObjectDirectory(cmGeneratorTarget const*) const
{
  // Compute the maximum length configuration name.
  std::string config_max;
  for(std::vector<std::string>::const_iterator
        i = this->Configurations.begin();
      i != this->Configurations.end(); ++i)
    {
    // Strip the subdirectory name out of the configuration name.
    std::string config = this->GetConfigName(*i);
    if(config.size() > config_max.size())
      {
      config_max = config;
      }
    }

  // Compute the maximum length full path to the intermediate
  // files directory for any configuration.  This is used to construct
  // object file names that do not produce paths that are too long.
  std::string dir_max;
  dir_max += this->GetCurrentBinaryDirectory();
  dir_max += "/";
  dir_max += config_max;
  dir_max += "/";
  return dir_max;
}

std::string
cmLocalVisualStudio6Generator
::GetConfigName(std::string const& configuration) const
{
  // Strip the subdirectory name out of the configuration name.
  std::string config = configuration;
  std::string::size_type pos = config.find_last_of(" ");
  config = config.substr(pos+1, std::string::npos);
  config = config.substr(0, config.size()-1);
  return config;
}

//----------------------------------------------------------------------------
bool
cmLocalVisualStudio6Generator
::CheckDefinition(std::string const& define) const
{
  // Perform the standard check first.
  if(!this->cmLocalGenerator::CheckDefinition(define))
    {
    return false;
    }

  // Now do the VS6-specific check.
  if(define.find_first_of(" ") != define.npos &&
     define.find_first_of("\"$;") != define.npos)
    {
    std::ostringstream e;
    e << "WARNING: The VS6 IDE does not support preprocessor definition "
      << "values with spaces and '\"', '$', or ';'.\n"
      << "CMake is dropping a preprocessor definition: " << define << "\n"
      << "Consider defining the macro in a (configured) header file.\n";
    cmSystemTools::Message(e.str().c_str());
    return false;
    }

  // Assume it is supported.
  return true;
}
