diff options
Diffstat (limited to 'Source/cmGlobalVisualStudio6Generator.cxx')
-rw-r--r-- | Source/cmGlobalVisualStudio6Generator.cxx | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx new file mode 100644 index 000000000..fe44e200e --- /dev/null +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -0,0 +1,424 @@ +/*============================================================================ + 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 "cmGlobalVisualStudio6Generator.h" +#include "cmLocalVisualStudio6Generator.h" +#include "cmMakefile.h" +#include "cmake.h" +#include "cmGeneratedFileStream.h" + +// Utility function to make a valid VS6 *.dsp filename out +// of a CMake target name: +// +std::string GetVS6TargetName(const std::string& targetName) +{ + std::string name(targetName); + + // Eliminate hyphens. VS6 cannot handle hyphens in *.dsp filenames... + // Replace them with underscores. + // + cmSystemTools::ReplaceString(name, "-", "_"); + + return name; +} + +cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator() +{ + this->FindMakeProgramFile = "CMakeVS6FindMake.cmake"; +} + +void cmGlobalVisualStudio6Generator +::EnableLanguage(std::vector<std::string>const& lang, + cmMakefile *mf, + bool optional) +{ + mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); + mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); + mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); + mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); + mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort"); + mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); + mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); + mf->AddDefinition("MSVC60", "1"); + this->GenerateConfigurations(mf); + this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); +} + +void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf) +{ + std::string fname= mf->GetRequiredDefinition("CMAKE_ROOT"); + const char* def= mf->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY"); + if(def) + { + fname = def; + } + else + { + fname += "/Templates"; + } + fname += "/CMakeVisualStudio6Configurations.cmake"; + if(!mf->ReadListFile(mf->GetCurrentListFile(), fname.c_str())) + { + cmSystemTools::Error("Cannot open ", fname.c_str(), + ". Please copy this file from the main " + "CMake/Templates directory and edit it for " + "your build configurations."); + } + else if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) + { + cmSystemTools::Error("CMAKE_CONFIGURATION_TYPES not set by ", + fname.c_str(), + ". Please copy this file from the main " + "CMake/Templates directory and edit it for " + "your build configurations."); + } +} + +std::string cmGlobalVisualStudio6Generator +::GenerateBuildCommand(const char* makeProgram, + const char *projectName, + const char* additionalOptions, + const char *targetName, + const char* config, + bool ignoreErrors, + bool) +{ + // Ingoring errors is not implemented in visual studio 6 + (void) ignoreErrors; + + // now build the test + std::vector<std::string> mp; + mp.push_back("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio" + "\\6.0\\Setup;VsCommonDir]/MSDev98/Bin"); + cmSystemTools::ExpandRegistryValues(mp[0]); + std::string originalCommand = makeProgram; + std::string makeCommand = + cmSystemTools::FindProgram(makeProgram, mp); + if(makeCommand.size() == 0) + { + std::string e = "Generator cannot find Visual Studio 6 msdev program \""; + e += originalCommand; + e += "\" specified by CMAKE_MAKE_PROGRAM cache entry. "; + e += "Please fix the setting."; + cmSystemTools::Error(e.c_str()); + return ""; + } + makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str()); + + // if there are spaces in the makeCommand, assume a full path + // and convert it to a path with no spaces in it as the + // RunSingleCommand does not like spaces +#if defined(_WIN32) && !defined(__CYGWIN__) + if(makeCommand.find(' ') != std::string::npos) + { + cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + } +#endif + makeCommand += " "; + makeCommand += projectName; + makeCommand += ".dsw /MAKE \""; + bool clean = false; + if ( targetName && strcmp(targetName, "clean") == 0 ) + { + clean = true; + targetName = "ALL_BUILD"; + } + if (targetName && strlen(targetName)) + { + makeCommand += targetName; + } + else + { + makeCommand += "ALL_BUILD"; + } + makeCommand += " - "; + if(config && strlen(config)) + { + makeCommand += config; + } + else + { + makeCommand += "Debug"; + } + if(clean) + { + makeCommand += "\" /CLEAN"; + } + else + { + makeCommand += "\" /BUILD"; + } + if ( additionalOptions ) + { + makeCommand += " "; + makeCommand += additionalOptions; + } + return makeCommand; +} + +///! Create a local generator appropriate to this Global Generator +cmLocalGenerator *cmGlobalVisualStudio6Generator::CreateLocalGenerator() +{ + cmLocalGenerator *lg = new cmLocalVisualStudio6Generator; + lg->SetGlobalGenerator(this); + return lg; +} + + +void cmGlobalVisualStudio6Generator::Generate() +{ + // first do the superclass method + this->cmGlobalVisualStudioGenerator::Generate(); + + // Now write out the DSW + this->OutputDSWFile(); +} + +// Write a DSW file to the stream +void cmGlobalVisualStudio6Generator +::WriteDSWFile(std::ostream& fout,cmLocalGenerator* root, + std::vector<cmLocalGenerator*>& generators) +{ + // Write out the header for a DSW file + this->WriteDSWHeader(fout); + + // Collect all targets under this root generator and the transitive + // closure of their dependencies. + TargetDependSet projectTargets; + TargetDependSet originalTargets; + this->GetTargetSets(projectTargets, originalTargets, root, generators); + OrderedTargetDependSet orderedProjectTargets(projectTargets); + + for(OrderedTargetDependSet::const_iterator + tt = orderedProjectTargets.begin(); + tt != orderedProjectTargets.end(); ++tt) + { + cmTarget* target = *tt; + cmMakefile* mf = target->GetMakefile(); + // Write the project into the DSW file + const char* expath = target->GetProperty("EXTERNAL_MSPROJECT"); + if(expath) + { + std::string project = target->GetName(); + std::string location = expath; + this->WriteExternalProject(fout, project.c_str(), + location.c_str(), target->GetUtilities()); + } + else + { + std::string dspname = GetVS6TargetName(target->GetName()); + std::string dir = target->GetMakefile()->GetStartOutputDirectory(); + dir = root->Convert(dir.c_str(), cmLocalGenerator::START_OUTPUT); + this->WriteProject(fout, dspname.c_str(), dir.c_str(), *target); + } + } + + // Write the footer for the DSW file + this->WriteDSWFooter(fout); +} + +void cmGlobalVisualStudio6Generator +::OutputDSWFile(cmLocalGenerator* root, + std::vector<cmLocalGenerator*>& generators) +{ + if(generators.size() == 0) + { + return; + } + std::string fname = root->GetMakefile()->GetStartOutputDirectory(); + fname += "/"; + fname += root->GetMakefile()->GetProjectName(); + fname += ".dsw"; + std::ofstream fout(fname.c_str()); + if(!fout) + { + cmSystemTools::Error("Error can not open DSW file for write: ", + fname.c_str()); + cmSystemTools::ReportLastSystemError(""); + return; + } + this->WriteDSWFile(fout, root, generators); +} + +// output the DSW file +void cmGlobalVisualStudio6Generator::OutputDSWFile() +{ + std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; + for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it) + { + this->OutputDSWFile(it->second[0], it->second); + } +} + +// Write a dsp file into the DSW file, +// Note, that dependencies from executables to +// the libraries it uses are also done here +void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout, + const char* dspname, + const char* dir, + cmTarget& target) +{ + fout << "#########################################################" + "######################\n\n"; + fout << "Project: \"" << dspname << "\"=" + << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n"; + fout << "Package=<5>\n{{{\n}}}\n\n"; + fout << "Package=<4>\n"; + fout << "{{{\n"; + VSDependSet const& depends = this->VSTargetDepends[&target]; + for(VSDependSet::const_iterator di = depends.begin(); + di != depends.end(); ++di) + { + const char* name = di->c_str(); + fout << "Begin Project Dependency\n"; + fout << "Project_Dep_Name " << GetVS6TargetName(name) << "\n"; + fout << "End Project Dependency\n"; + } + fout << "}}}\n\n"; + + UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target); + if(ui != this->UtilityDepends.end()) + { + const char* uname = ui->second.c_str(); + fout << "Project: \"" << uname << "\"=" + << dir << "\\" << uname << ".dsp - Package Owner=<4>\n\n"; + fout << + "Package=<5>\n{{{\n}}}\n\n" + "Package=<4>\n" + "{{{\n" + "Begin Project Dependency\n" + "Project_Dep_Name " << dspname << "\n" + "End Project Dependency\n" + "}}}\n\n"; + ; + } +} + + +// Write a dsp file into the DSW file, +// Note, that dependencies from executables to +// the libraries it uses are also done here +void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout, + const char* name, + const char* location, + const std::set<cmStdString>& dependencies) +{ + fout << "#########################################################" + "######################\n\n"; + fout << "Project: \"" << name << "\"=" + << location << " - Package Owner=<4>\n\n"; + fout << "Package=<5>\n{{{\n}}}\n\n"; + fout << "Package=<4>\n"; + fout << "{{{\n"; + + + std::set<cmStdString>::const_iterator i, end; + // write dependencies. + i = dependencies.begin(); + end = dependencies.end(); + for(;i!= end; ++i) + { + fout << "Begin Project Dependency\n"; + fout << "Project_Dep_Name " << GetVS6TargetName(*i) << "\n"; + fout << "End Project Dependency\n"; + } + fout << "}}}\n\n"; +} + + + +// Standard end of dsw file +void cmGlobalVisualStudio6Generator::WriteDSWFooter(std::ostream& fout) +{ + fout << "######################################################" + "#########################\n\n"; + fout << "Global:\n\n"; + fout << "Package=<5>\n{{{\n}}}\n\n"; + fout << "Package=<3>\n{{{\n}}}\n\n"; + fout << "#####################################################" + "##########################\n\n"; +} + + +// ouput standard header for dsw file +void cmGlobalVisualStudio6Generator::WriteDSWHeader(std::ostream& fout) +{ + fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n"; + fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n"; +} + +//---------------------------------------------------------------------------- +std::string +cmGlobalVisualStudio6Generator::WriteUtilityDepend(cmTarget* target) +{ + std::string pname = target->GetName(); + pname += "_UTILITY"; + pname = GetVS6TargetName(pname.c_str()); + std::string fname = target->GetMakefile()->GetStartOutputDirectory(); + fname += "/"; + fname += pname; + fname += ".dsp"; + cmGeneratedFileStream fout(fname.c_str()); + fout.SetCopyIfDifferent(true); + fout << + "# Microsoft Developer Studio Project File - Name=\"" + << pname << "\" - Package Owner=<4>\n" + "# Microsoft Developer Studio Generated Build File, Format Version 6.00\n" + "# ** DO NOT EDIT **\n" + "\n" + "# TARGTYPE \"Win32 (x86) Generic Project\" 0x010a\n" + "\n" + "CFG=" << pname << " - Win32 Debug\n" + "!MESSAGE \"" << pname << " - Win32 Debug\"" + " (based on \"Win32 (x86) Generic Project\")\n" + "!MESSAGE \"" << pname << " - Win32 Release\" " + "(based on \"Win32 (x86) Generic Project\")\n" + "!MESSAGE \"" << pname << " - Win32 MinSizeRel\" " + "(based on \"Win32 (x86) Generic Project\")\n" + "!MESSAGE \"" << pname << " - Win32 RelWithDebInfo\" " + "(based on \"Win32 (x86) Generic Project\")\n" + "\n" + "# Begin Project\n" + "# Begin Target\n" + "# Name \"" << pname << " - Win32 Debug\"\n" + "# Name \"" << pname << " - Win32 Release\"\n" + "# Name \"" << pname << " - Win32 MinSizeRel\"\n" + "# Name \"" << pname << " - Win32 RelWithDebInfo\"\n" + "# End Target\n" + "# End Project\n" + ; + return pname; +} + +//---------------------------------------------------------------------------- +void cmGlobalVisualStudio6Generator +::GetDocumentation(cmDocumentationEntry& entry) const +{ + entry.Name = this->GetName(); + entry.Brief = "Generates Visual Studio 6 project files."; + entry.Full = ""; +} + +//---------------------------------------------------------------------------- +void +cmGlobalVisualStudio6Generator +::AppendDirectoryForConfig(const char* prefix, + const char* config, + const char* suffix, + std::string& dir) +{ + if(config) + { + dir += prefix; + dir += config; + dir += suffix; + } +} |