| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930 | /*=========================================================================  Program:   CMake - Cross-Platform Makefile Generator  Module:    $RCSfile$  Language:  C++  Date:      $Date$  Version:   $Revision$  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.     This software is distributed WITHOUT ANY WARRANTY; without even      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      PURPOSE.  See the above copyright notices for more information.=========================================================================*/#include "cmGlobalVisualStudio7Generator.h"#include "cmLocalVisualStudio7Generator.h"#include "cmMakefile.h"#include "cmSystemTools.h"#include "cmSourceFile.h"#include "cmCacheManager.h"cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(){}cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator(){}void cmLocalVisualStudio7Generator::Generate(bool /* fromTheTop */){  this->OutputVCProjFile();}// TODO// for CommandLine= need to repleace quotes with "// write out configurationsvoid cmLocalVisualStudio7Generator::OutputVCProjFile(){   // If not an in source build, then create the output directory  if(strcmp(m_Makefile->GetStartOutputDirectory(),            m_Makefile->GetHomeDirectory()) != 0)    {    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))      {      cmSystemTools::Error("Error creating directory ",                           m_Makefile->GetStartOutputDirectory());      }    }    m_LibraryOutputPath = "";  if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))    {    m_LibraryOutputPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");    }  if(m_LibraryOutputPath.size())    {    // make sure there is a trailing slash    if(m_LibraryOutputPath[m_LibraryOutputPath.size()-1] != '/')      {      m_LibraryOutputPath += "/";      }    }  m_ExecutableOutputPath = "";  if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))    {    m_ExecutableOutputPath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");    }  if(m_ExecutableOutputPath.size())    {    // make sure there is a trailing slash    if(m_ExecutableOutputPath[m_ExecutableOutputPath.size()-1] != '/')      {      m_ExecutableOutputPath += "/";      }    }    // Create the VCProj or set of VCProj's for libraries and executables  // clear project names  m_CreatedProjectNames.clear();  // build any targets  cmTargets &tgts = m_Makefile->GetTargets();  for(cmTargets::iterator l = tgts.begin();       l != tgts.end(); l++)    {    // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace    // so don't build a projectfile for it    if ((l->second.GetType() != cmTarget::INSTALL_FILES)        && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)        && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))      {      this->CreateSingleVCProj(l->first.c_str(),l->second);      }    }}void cmLocalVisualStudio7Generator::CreateSingleVCProj(const char *lname, cmTarget &target){  // add to the list of projects  std::string pname = lname;  m_CreatedProjectNames.push_back(pname);  // create the dsp.cmake file  std::string fname;  fname = m_Makefile->GetStartOutputDirectory();  fname += "/";  fname += lname;  fname += ".vcproj";  // save the name of the real dsp file  std::string realVCProj = fname;  fname += ".cmake";  std::ofstream fout(fname.c_str());  if(!fout)    {    cmSystemTools::Error("Error Writing ", fname.c_str());    }  this->WriteVCProjFile(fout,lname,target);  fout.close();  // if the dsp file has changed, then write it.  cmSystemTools::CopyFileIfDifferent(fname.c_str(), realVCProj.c_str());}void cmLocalVisualStudio7Generator::AddVCProjBuildRule(cmSourceGroup& sourceGroup){  std::string dspname = *(m_CreatedProjectNames.end()-1);  if(dspname == "ALL_BUILD")  {    return;  }  dspname += ".vcproj.cmake";  std::string makefileIn = m_Makefile->GetStartDirectory();  makefileIn += "/";  makefileIn += "CMakeLists.txt";  makefileIn = cmSystemTools::ConvertToOutputPath(makefileIn.c_str());  std::string dsprule = "${CMAKE_COMMAND}";  m_Makefile->ExpandVariablesInString(dsprule);  dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());  std::string args = makefileIn;  args += " -H";  args +=    cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());  args += " -S";  args +=     cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());  args += " -O";  args +=     cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());  args += " -B";  args +=     cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());  args += "";  m_Makefile->ExpandVariablesInString(args);  std::string configFile =     m_Makefile->GetDefinition("CMAKE_ROOT");  configFile += "/Templates/CMakeWindowsSystemConfig.cmake";  std::vector<std::string> listFiles = m_Makefile->GetListFiles();  bool found = false;  for(std::vector<std::string>::iterator i = listFiles.begin();      i != listFiles.end(); ++i)    {    if(*i == configFile)      {      found  = true;      }    }  if(!found)    {    listFiles.push_back(configFile);    }    std::vector<std::string> outputs;  outputs.push_back(dspname);  cmCustomCommand cc(makefileIn.c_str(), dsprule.c_str(),                     args.c_str(),                     listFiles,                      outputs);  sourceGroup.AddCustomCommand(cc);}void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout,                                                         const char *libName,                                                        const cmTarget &target){  std::vector<std::string> *configs =     static_cast<cmGlobalVisualStudio7Generator *>(m_GlobalGenerator)->GetConfigurations();  fout << "\t<Configurations>\n";  for( std::vector<std::string>::iterator i = configs->begin();       i != configs->end(); ++i)    {    this->WriteConfiguration(fout, i->c_str(), libName, target);    }  fout << "\t</Configurations>\n";}void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,                                              const char* configName,                                             const char *libName,                                             const cmTarget &target){   const char* mfcFlag = m_Makefile->GetDefinition("CMAKE_MFC_FLAG");  if(!mfcFlag)    {    mfcFlag = "0";    }  fout << "\t\t<Configuration\n"       << "\t\t\tName=\"" << configName << "|Win32\"\n"       << "\t\t\tOutputDirectory=\"" << configName << "\"\n";  // This is an internal type to Visual Studio, it seems that:  // 4 == static library  // 2 == dll  // 1 == executable  // 10 == utility   const char* configType = "10";  switch(target.GetType())    {     case cmTarget::STATIC_LIBRARY:      configType = "4";      break;    case cmTarget::SHARED_LIBRARY:    case cmTarget::MODULE_LIBRARY:      configType = "2";      break;    case cmTarget::EXECUTABLE:     case cmTarget::WIN32_EXECUTABLE:        configType = "1";      break;     case cmTarget::UTILITY:      configType = "10";    default:      break;    }    fout << "\t\t\tIntermediateDirectory=\".\\" << configName << "\"\n"       << "\t\t\tConfigurationType=\"" << configType << "\"\n"       << "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"       << "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"       << "\t\t\tCharacterSet=\"2\">\n";  fout << "\t\t\t<Tool\n"       << "\t\t\t\tName=\"VCCLCompilerTool\"\n"       << "\t\t\t\tAdditionalOptions=\"";  std::string flags;  if(target.HasCxx())    {    flags = m_Makefile->GetDefinition("CMAKE_CXX_FLAGS");    }  else    {    if(m_Makefile->GetDefinition("CMAKE_C_FLAGS"))      {      flags = m_Makefile->GetDefinition("CMAKE_C_FLAGS");      }    }  cmSystemTools::ReplaceString(flags, "\"", """);  fout << flags;  fout << " -DCMAKE_INTDIR=\\"" << configName << "\\""        << "\"\n";  fout << "\t\t\t\tAdditionalIncludeDirectories=\"";  std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();  std::vector<std::string>::iterator i = includes.begin();  for(;i != includes.end(); ++i)    {    std::string ipath = this->ConvertToXMLOutputPath(i->c_str());    fout << ipath << ";";    }  fout << "\"\n";  // Optimization = 0  None Debug  /O0// Optimization = 1  MinSize     /O1// Optimization = 2  MaxSpeed    /O2// Optimization = 3  Max Optimization   /O3// RuntimeLibrary = 0 /MT   multithread// RuntimeLibrary = 1 /MTd  multithread debug// RuntimeLibrary = 2 /MD   multithread dll// RuntimeLibrary = 3 /MDd  multithread dll debug// RuntimeLibrary = 4 /ML   single thread// RuntimeLibrary = 5 /MLd  single thread debug// InlineFunctionExpansion = 0 none// InlineFunctionExpansion = 1 when inline keyword// InlineFunctionExpansion = 2 any time you can  if(strcmp(configName, "Debug") == 0)    {    fout << "\t\t\t\tOptimization=\"0\"\n"         << "\t\t\t\tRuntimeLibrary=\"3\"\n"         << "\t\t\t\tInlineFunctionExpansion=\"0\"\n"         << "\t\t\t\tPreprocessorDefinitions=\"WIN32,_DEBUG,_WINDOWS";    }  else if(strcmp(configName, "Release") == 0)    {    fout << "\t\t\t\tOptimization=\"2\"\n"         << "\t\t\t\tRuntimeLibrary=\"2\"\n"         << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"         << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";    }  else if(strcmp(configName, "MinSizeRel") == 0)    {    fout << "\t\t\t\tOptimization=\"1\"\n"         << "\t\t\t\tRuntimeLibrary=\"2\"\n"         << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"         << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";    }  else if(strcmp(configName, "RelWithDebInfo") == 0)    {    fout << "\t\t\t\tOptimization=\"2\"\n"         << "\t\t\t\tRuntimeLibrary=\"2\"\n"         << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"         << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";    }  if(target.GetType() == cmTarget::SHARED_LIBRARY     || target.GetType() == cmTarget::MODULE_LIBRARY)    {    fout << "," << libName << "_EXPORTS";    }  this->OutputDefineFlags(fout);  fout << "\"\n";  if(m_Makefile->IsOn("CMAKE_CXX_USE_RTTI"))    {    fout << "\t\t\t\tRuntimeTypeInfo=\"TRUE\"\n";    }  fout << "\t\t\t\tAssemblerListingLocation=\"" << configName << "\"\n";  fout << "\t\t\t\tObjectFile=\"" << configName << "\\\"\n";  fout << "\t\t\t\tWarningLevel=\"" << m_Makefile->GetDefinition("CMAKE_CXX_WARNING_LEVEL") << "\"\n";  fout << "\t\t\t\tDetect64BitPortabilityProblems=\"TRUE\"\n"       << "\t\t\t\tDebugInformationFormat=\"3\"";  fout << "/>\n";  // end of <Tool Name=VCCLCompilerTool  fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n";  fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n"       << "AdditionalIncludeDirectories=\"";  for(i = includes.begin();i != includes.end(); ++i)    {    std::string ipath = this->ConvertToXMLOutputPath(i->c_str());    fout << ipath << ";";    }  fout << "\"\n/>\n";  fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n";  fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"";  this->OutputTargetRules(fout, target, libName);  fout << "/>\n";  fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n";  this->OutputBuildTool(fout, configName, libName, target);  fout << "\t\t</Configuration>\n";}void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,                                          const char* configName,                                          const char *libName,                                          const cmTarget &target){   std::string temp;  switch(target.GetType())    {    case cmTarget::STATIC_LIBRARY:    {      std::string libpath = m_LibraryOutputPath +         "$(OutDir)/" + libName + ".lib";      fout << "\t\t\t<Tool\n"           << "\t\t\t\tName=\"VCLibrarianTool\"\n"           << "\t\t\t\t\tOutputFile=\""            << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << ".\"/>\n";      break;    }    case cmTarget::SHARED_LIBRARY:    case cmTarget::MODULE_LIBRARY:      fout << "\t\t\t<Tool\n"           << "\t\t\t\tName=\"VCLinkerTool\"\n"           << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n"           << "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib ";      this->OutputLibraries(fout, configName, libName, target);      fout << "\"\n";      temp = m_LibraryOutputPath;      temp += configName;      temp += "/";      temp += libName;      temp += ".dll";      fout << "\t\t\t\tOutputFile=\""            << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";      fout << "\t\t\t\tLinkIncremental=\"1\"\n";      fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n";      fout << "\t\t\t\tAdditionalLibraryDirectories=\"";      this->OutputLibraryDirectories(fout, configName, libName, target);      fout << "\"\n";      this->OutputModuleDefinitionFile(fout, target);      temp = m_LibraryOutputPath;      temp += "$(OutDir)";      temp += "/";      temp += libName;      temp += ".pdb";      fout << "\t\t\t\tProgramDatabaseFile=\"" <<         this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";      if(strcmp(configName, "Debug") == 0         || strcmp(configName, "RelWithDebInfo") == 0)        {        fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";        }      fout << "\t\t\t\tStackReserveSize=\""            << m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"\n";      temp = m_ExecutableOutputPath;      temp += configName;      temp += "/";      temp += libName;      temp += ".lib";      fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";      break;    case cmTarget::EXECUTABLE:    case cmTarget::WIN32_EXECUTABLE:      fout << "\t\t\t<Tool\n"           << "\t\t\t\tName=\"VCLinkerTool\"\n"           << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n"           << "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib ";      this->OutputLibraries(fout, configName, libName, target);      fout << "\"\n";      temp = m_ExecutableOutputPath;      temp += configName;      temp += "/";      temp += libName;      temp += ".exe";      fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";      fout << "\t\t\t\tLinkIncremental=\"1\"\n";      fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n";      fout << "\t\t\t\tAdditionalLibraryDirectories=\"";      this->OutputLibraryDirectories(fout, configName, libName, target);      fout << "\"\n";      fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath            << "$(OutDir)\\" << libName << ".pdb\"\n";      if(strcmp(configName, "Debug") == 0          || strcmp(configName, "RelWithDebInfo") == 0)        {        fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";        }      if( target.GetType() == cmTarget::EXECUTABLE)        {        fout << "\t\t\t\tSubSystem=\"1\"\n";        }      else        {              fout << "\t\t\t\tSubSystem=\"2\"\n";        }      fout << "\t\t\t\tStackReserveSize=\""            << m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"/>\n";      break;    case cmTarget::UTILITY:      break;    }}void cmLocalVisualStudio7Generator::OutputModuleDefinitionFile(std::ostream& fout,                                                     const cmTarget &target){  std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();       i != classes.end(); i++)    {      if(cmSystemTools::UpperCase((*i)->GetSourceExtension()) == "DEF")      {      fout << "\t\t\t\tModuleDefinitionFile=\""           << this->ConvertToXMLOutputPath((*i)->GetFullPath().c_str())           << "\"\n";      return;      }    }  }void cmLocalVisualStudio7Generator::OutputLibraryDirectories(std::ostream& fout,                                                   const char*,                                                   const char*,                                                   const cmTarget &tgt){   bool hasone = false;  if(m_LibraryOutputPath.size())    {    hasone = true;    std::string temp = m_LibraryOutputPath;    temp += "$(INTDIR)";        fout << this->ConvertToXMLOutputPath(temp.c_str()) << "," <<       this->ConvertToXMLOutputPath(m_LibraryOutputPath.c_str());    }  if(m_ExecutableOutputPath.size())    {    hasone = true;    std::string temp = m_ExecutableOutputPath;    temp += "$(INTDIR)";     fout << this->ConvertToXMLOutputPath(temp.c_str()) << "," <<       this->ConvertToXMLOutputPath(m_ExecutableOutputPath.c_str());    }      std::set<std::string> pathEmitted;  std::vector<std::string>::const_iterator i;  const std::vector<std::string>& libdirs = tgt.GetLinkDirectories();  for(i = libdirs.begin(); i != libdirs.end(); ++i)    {    std::string lpath = *i;    if(lpath[lpath.size()-1] != '/')      {      lpath += "/";      }    if(pathEmitted.insert(lpath).second)      {      if(hasone)        {        fout << ",";        }      std::string lpathi = lpath + "$(INTDIR)";          fout << this->ConvertToXMLOutputPath(lpathi.c_str()) << "," << lpath;      hasone = true;      }    }}void cmLocalVisualStudio7Generator::OutputLibraries(std::ostream& fout,                                          const char* configName,                                          const char* libName,                                          const cmTarget &target){  const cmTarget::LinkLibraries& libs = target.GetLinkLibraries();  cmTarget::LinkLibraries::const_iterator j;  for(j = libs.begin(); j != libs.end(); ++j)    {     if(j->first != libName)      {      std::string lib = j->first;      if(j->first.find(".lib") == std::string::npos)        {        lib += ".lib";        }      lib = this->ConvertToXMLOutputPath(lib.c_str());      if (j->second == cmTarget::GENERAL          || (j->second == cmTarget::DEBUG && strcmp(configName, "DEBUG") == 0)          || (j->second == cmTarget::OPTIMIZED && strcmp(configName, "DEBUG") != 0))        {        fout << lib << " ";        }      }    }}void cmLocalVisualStudio7Generator::OutputDefineFlags(std::ostream& fout){  std::string defs = m_Makefile->GetDefineFlags();  std::string::size_type pos = defs.find("-D");  bool done = pos == std::string::npos;  if(!done)    {    fout << ",";    }  while(!done)    {    std::string::size_type nextpos = defs.find("-D", pos+2);    std::string define;    if(nextpos != std::string::npos)      {      define = defs.substr(pos+2, nextpos - pos -3);      }    else      {      define = defs.substr(pos+2);      done = true;      }    cmSystemTools::ReplaceString(define, "\"", "");    fout << define << ",";    if(!done)      {      pos = defs.find("-D", nextpos);      }    } }void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,                                  const char *libName,                                 cmTarget &target){  // get the configurations  std::vector<std::string> *configs =     static_cast<cmGlobalVisualStudio7Generator *>(m_GlobalGenerator)->GetConfigurations();    // We may be modifying the source groups temporarily, so make a copy.  std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();    // get the classes from the source lists then add them to the groups  std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();       i != classes.end(); i++)    {    // Add the file to the list of sources.    std::string source = (*i)->GetFullPath();    if(cmSystemTools::UpperCase((*i)->GetSourceExtension()) == "DEF")      {      m_ModuleDefinitionFile = (*i)->GetFullPath();      }        cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),                                                             sourceGroups);    sourceGroup.AddSource(source.c_str(), *i);    }    // add any custom rules to the source groups  for (std::vector<cmCustomCommand>::const_iterator cr =          target.GetCustomCommands().begin();        cr != target.GetCustomCommands().end(); ++cr)    {    cmSourceGroup& sourceGroup =       m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),                                  sourceGroups);    cmCustomCommand cc(*cr);    cc.ExpandVariables(*m_Makefile);    sourceGroup.AddCustomCommand(cc);    }    // open the project  this->WriteProjectStart(fout, libName, target, sourceGroups);  // write the configuration information  this->WriteConfigurations(fout, libName, target);  fout << "\t<Files>\n";  // Find the group in which the CMakeLists.txt source belongs, and add  // the rule to generate this VCProj file.  for(std::vector<cmSourceGroup>::reverse_iterator sg = sourceGroups.rbegin();      sg != sourceGroups.rend(); ++sg)    {    if(sg->Matches("CMakeLists.txt"))      {      this->AddVCProjBuildRule(*sg);      break;      }        }    // Loop through every source group.  for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();      sg != sourceGroups.end(); ++sg)    {    const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();    // If the group is empty, don't write it at all.    if(buildRules.empty())      { continue; }        // If the group has a name, write the header.    std::string name = sg->GetName();    if(name != "")      {      this->WriteVCProjBeginGroup(fout, name.c_str(), "");      }        // Loop through each build rule in the source group.    for(cmSourceGroup::BuildRules::const_iterator cc =          buildRules.begin(); cc != buildRules.end(); ++ cc)      {      std::string source = cc->first;      const cmSourceGroup::Commands& commands = cc->second.m_Commands;      const char* compileFlags = 0;      if(cc->second.m_SourceFile)        {        compileFlags = cc->second.m_SourceFile->GetProperty("COMPILE_FLAGS");        }      if (source != libName || target.GetType() == cmTarget::UTILITY)        {        fout << "\t\t\t<File\n";        std::string d = cmSystemTools::ConvertToOutputPath(source.c_str());        // remove double quotes from the string        cmSystemTools::ReplaceString(d, "\"", "");        // Tell MS-Dev what the source is.  If the compiler knows how to        // build it, then it will.        fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";        if (!commands.empty())          {          cmSourceGroup::CommandFiles totalCommand;          std::string totalCommandStr;          totalCommandStr = this->CombineCommands(commands, totalCommand,                                                  source.c_str());          const char* comment = totalCommand.m_Comment.c_str();          this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(),                                 (*comment?comment:"Custom Rule"),                                totalCommand.m_Depends,                                totalCommand.m_Outputs, compileFlags);          }        else if(compileFlags)          {          for(std::vector<std::string>::iterator i = configs->begin();               i != configs->end(); ++i)            {            fout << "\t\t\t\t<FileConfiguration\n"                 << "\t\t\t\t\tName=\""  << *i << "|Win32\">\n"                 << "\t\t\t\t\t<Tool\n"                 << "\t\t\t\t\tName=\"VCCLCompilerTool\"\n"                 << "\t\t\t\t\tAdditionalOptions=\""                 << compileFlags << "\"/>\n"                 << "\t\t\t\t</FileConfiguration>\n";            }          }        fout << "\t\t\t</File>\n";        }      }        // If the group has a name, write the footer.    if(name != "")      {      this->WriteVCProjEndGroup(fout);      }    }    fout << "\t</Files>\n";  // Write the VCProj file's footer.  this->WriteVCProjFooter(fout);}void cmLocalVisualStudio7Generator::WriteCustomRule(std::ostream& fout,                                          const char* source,                                          const char* command,                                          const char* comment,                                          const std::set<std::string>& depends,                                          const std::set<std::string>& outputs,                                          const char* compileFlags){  std::string cmd = command;  cmSystemTools::ReplaceString(cmd, "\"", """);  std::vector<std::string>::iterator i;  std::vector<std::string> *configs =     static_cast<cmGlobalVisualStudio7Generator *>(m_GlobalGenerator)->GetConfigurations();  for(i = configs->begin(); i != configs->end(); ++i)    {    fout << "\t\t\t\t<FileConfiguration\n";    fout << "\t\t\t\t\tName=\"" << *i << "|Win32\">\n";    if(compileFlags)      {      fout << "\t\t\t\t\t<Tool\n"           << "\t\t\t\t\tName=\"VCCLCompilerTool\"\n"           << "\t\t\t\t\tAdditionalOptions=\""           << compileFlags << "\"/>\n";      }    fout << "\t\t\t\t\t<Tool\n"         << "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"         << "\t\t\t\t\tDescription=\"Building " << comment;    std::set<std::string>::const_iterator it;    for ( it = outputs.begin(); it != outputs.end(); it ++ )      {      fout << " " << *it;      }    fout << "\"\n"         << "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n"         << "\t\t\t\t\tAdditionalDependencies=\"";    // Write out the dependencies for the rule.    std::string temp;    for(std::set<std::string>::const_iterator d = depends.begin();        d != depends.end(); ++d)      {      fout << this->ConvertToXMLOutputPath(d->c_str())           << ";";      }    fout << "\"\n";    fout << "\t\t\t\t\tOutputs=\"";    if(outputs.size() == 0)      {      fout << source << "_force";      }        bool first = true;    // Write a rule for every output generated by this command.    for(std::set<std::string>::const_iterator output = outputs.begin();        output != outputs.end(); ++output)      {      if(!first)        {        fout << ";";        }      else        {        first = false;        }      fout << output->c_str();      }    fout << "\"/>\n";    fout << "\t\t\t\t</FileConfiguration>\n";    }}void cmLocalVisualStudio7Generator::WriteVCProjBeginGroup(std::ostream& fout,                                         const char* group,                                        const char* ){  fout << "\t\t<Filter\n"       << "\t\t\tName=\"" << group << "\"\n"       << "\t\t\tFilter=\"\">\n";}void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout){  fout << "\t\t</Filter>\n";}std::stringcmLocalVisualStudio7Generator::CombineCommands(  const cmSourceGroup::Commands &commands,  cmSourceGroup::CommandFiles &totalCommand,  const char *source)  {  // Loop through every custom command generating code from the  // current source.  // build up the depends and outputs and commands   std::string totalCommandStr = "";  std::string temp;  for(cmSourceGroup::Commands::const_iterator c = commands.begin();      c != commands.end(); ++c)    {    temp=       cmSystemTools::ConvertToOutputPath(c->second.m_Command.c_str());     totalCommandStr += temp;    totalCommandStr += " ";    totalCommandStr += c->second.m_Arguments;    totalCommandStr += "\n";    totalCommand.Merge(c->second);    totalCommand.m_Comment = c->second.m_Comment.c_str();    }        // Create a dummy file with the name of the source if it does  // not exist  if(totalCommand.m_Outputs.empty())    {     std::string dummyFile = m_Makefile->GetStartOutputDirectory();    dummyFile += "/";    dummyFile += source;    if(!cmSystemTools::FileExists(dummyFile.c_str()))      {      std::ofstream fout(dummyFile.c_str());      fout << "Dummy file created by cmake as unused source for utility command.\n";      }    }  return totalCommandStr;}// look for custom rules on a target and collect them togethervoid cmLocalVisualStudio7Generator::OutputTargetRules(std::ostream& fout,                                            const cmTarget &target,                                             const char *libName){  if (target.GetType() >= cmTarget::UTILITY)    {    return;    }    // Find the group in which the lix exe custom rules belong  bool init = false;  for (std::vector<cmCustomCommand>::const_iterator cr =          target.GetCustomCommands().begin();        cr != target.GetCustomCommands().end(); ++cr)    {    cmCustomCommand cc(*cr);    cc.ExpandVariables(*m_Makefile);    if (cc.GetSourceName() == libName)      {      if(!init)        {        fout << "\nCommandLine=\"";        init = true;        }      std::string args = cc.GetArguments();      cmSystemTools::ReplaceString(args, "\"", """);      fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " << args << "\n";      }    }  if (init)    {    fout << "\"";    }}void cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,                                                  const char *libName,                                                 const cmTarget &,                                                  std::vector<cmSourceGroup> &){  fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"       << "<VisualStudioProject\n"       << "\tProjectType=\"Visual C++\"\n"       << "\tVersion=\"7.00\"\n"       << "\tName=\"" << libName << "\"\n"       << "\tSccProjectName=\"\"\n"       << "\tSccLocalPath=\"\"\n"       << "\tKeyword=\"Win32Proj\">\n"       << "\t<Platforms>\n"       << "\t\t<Platform\n\t\t\tName=\"Win32\"/>\n"       << "\t</Platforms>\n";}void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout){  fout << "\t<Globals>\n"       << "\t</Globals>\n"       << "</VisualStudioProject>\n";}std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(const char* path){  std::string ret = cmSystemTools::ConvertToOutputPath(path);  cmSystemTools::ReplaceString(ret, "\"", """);  return ret;}std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(const char* path){  std::string ret = cmSystemTools::ConvertToOutputPath(path);  cmSystemTools::ReplaceString(ret, "\"", "");  return ret;}
 |